2013/02/14

Unity and properties/accessors

As mentioned in the previous post I'd like to relate my experience with using properties in Unity and how to make them work properly. Properties are a C# feature and not available in UnityScript (another reason to ditch UnityScript). To help demonstrate what I mean I will be using a "circle" class.
public class Circle{
 public float radius;
}

What are properties?

As we can see radius is public and there is nothing stopping someone from putting in nonsensical values like negative numbers. Since we are in Euclidean geometry there is no such thing as "anti-length" and we need some way to restrict the value of radius to positive numbers. One solution would be to make radius a pivate member and use getters and setters:

public class Circle{
 private float _radius;
 public void SetRadius(float value){
   _radius = Mathf.Max(0, value);
 }
 public float GetRadius(){
  return _radius;
 }
}
(the underscore in front of radius is there to mark it as a member variable; it's just a convention, not mandatory) This gets the job done, but it's ugly and bloats the syntax. What we need instead is some sort of variable/function hybrid that acts like a messenger. This is where properties come in. Here is the same code as above, except using properties:

public class Circle{
 private float _radius;
 public float radius{
  get{return _radius;}
  set{_radius = Mathf.Max(0, value);}
 }
}
The property looks like a function that missing the brackets for parameters and it is treated like a variable in coding. Whenever we assign a value to it by using the "=" sign we actually call the set and when we use it in computation we call the get. value always refers to the value on the right hand side of the "=" sign. Here is an example:
myCircle.radius = -3; //calls set and sets _radius to 0
Debug.Log(myCircle.radius); //calls get and returns 0
}

Why should you use properties?

As you can see accessors allow us to expose member variables in a controlled fashion. You can put up restrictions on what a certain variable can hold. You can also create read-only "variables" by omitting the set part. Let's say your circle class has several formulae using the circumference and you don't want to type the formula every time. Here is what it would look like using an accessor:
public class Circle{
 private float _radius;
 public float radius{
  get{return _radius;}
  set{_radius = Mathf.Max(0, value);}
 }
 public float circumference{
  get{return Mathf.Pi * radius * radius;}
 }
}
There is no such thing as a "circumference" variable, instead its value is computed on the fly, yet you can still use it as if it were an actual variable:
float volume = height * myCircle.circumference;
Unity handes rotation using quaternions but you can still use Euler angles in the editor and in scripting, this is (most likely) the result of using properties as well. Properties are also great for exposing member variables in custom inspectors, like I did or Grid Framework. Unfortunately there is a problem.

Member varibles and the editor

You can treat the property just like any other variable when writing a custom inspector. However, once you hit play you will notice that your values have been reset and once you exit play mode or change the scene or anything else your values reset again. This is because the properties cannot actually store anything, they just serve to expose private members. The values of private members don't stick though, that's why everything gets reset. The solution is to use [SerializeField]:

public class Circle{,
 [SerializeField]
 private float _radius;
 public float radius{
  get{return _radius;}
 set{_radius = Mathf.Max(0, value);}
 }
 public float circumference{
  get{return Mathf.Pi * radius * radius;}
 }
}
That's it, now your member variable will get serialized and will be remembered. It took me a while to find this, but I was finally able to throw out quite a lot of ugly workarounds. And now there is no reason not to use properties anymore. Let's end this post by using properties to limit the value of a float variable to something appropriate for angles:
private float _angle;
public float angle{
 get{return _angle;}
 set{return value >= 0 ? value % 360 : 360 + (value % 360);}
}

2013/02/12

Grid Framework version 1.2.2 released

Update time. Let's go over what's new:

New example: sliding block puzzle

It might not look like much, but this is the most advanced example yet; it's similar to the movement with obstacles example where we use a matrix to store which tiles are allowed and which are forbidden. The tricky part is that now objects can span more than one tile and all of them have to be free. The solution is to break up the obstacle into one tile large parts, then check them all individually and finally assemble the answer from the individual answers.
The end result is that it feels like collision without actually using collision. Now, you might be wondering why not just use actual collision detection? For one, Unity's collision detection requires you to move objects through the physics engine instead of directly. This means instead of moving the block like you would in real life you need to use force, like dragging the block with a rubber band. This feels just wrong, especially on a touch device. If you move objects directly (i.e. using their Transform component) the physics engine is likely to miss intersections. The other reason is that Unity's collision detection just isn't made for packing objects together this tighly, sooner or later things will just randomly  fly in all directions like the puzzle exploded or something.
Don't get me wrong, PhysiX was certainly developed by talented people who know more than I do, but it was written with 3D action games in mind and trying to get it to work in such a scenrio is like trying to fit a square peg into a round hole; you might get it to kind of work well enough eventually, but in the time it took you you might as well have written your own solution which you have proper control over. Thanks to Grid Framework we can automate all the unit conversion between world space and grid coordinates.

Changes: I removed the minimumSpacing (rectangular grids) and minimumRadius (hex grids) variables because they were stupid. The reason why they existed in the first place was to prevent the user from setting too low or nonsensical values for spacing and radius. The proper way to do this would be to use accessors (also called properties), but Unity's editor scripting documentation is rather lacking, so I couldn't figure out how to make the values not reset all the time.
I finally found the solution (that's a topic for another time) and now I hardcoded a lower limit of 0.1 for both. I think that's a reasonable value, but if you need to go lower please let me know. The way it works now is that if you try to set the value to anything lower than 0.1 it will automatically default to 0.1. I was also able to get rid of other ugly parts inside the source code and clean things up thanks to accessors, but I don't think you will notice any difference
In terms of scripting this has no real consequences for you, just use spacing and radius like you did before.

Fixes: One major bug was a typo that could prevent the project from building. I also removed the redundant "Use Custom Rendering Range" flag from the inspector, now opening or closing the "Custom Rendering Range" foldout toggles the value (in terms of scripting the varaible still exists, it's just the way you set it in the inspector). Speaking of inspector and foldout, previously the state of the "Draw & Render Settings" foldout reset each time you entered or exited play mode. Now the settings will stick and it will be individual for each grid type. There is also the obligatory under-the-hoods improvements, but there is nothing particular worth mentioning there.

2013/01/01

Happy New Year

A happy new year to everyone! This has been quite a year for me, so what better opportunity to recap the birth process and evolution of Grid and set the plans for this year?

How it all began
One day I was sitting at my computer, trying to place blocks in Unity, thinking how great it would be if there was some sort of extension, a framework if you will, that would auto snap objects to a grid of my choice. Unity already has some form of grid built in, but it's rather poor to say the least. Unfortunately a quick Google search didn't yield anything useful, so was left waiting for someone who knew how to program a copmputer to make such an extension. Then it struck me: I am someone and I know how to program a computer!

The first draft
So I sat down, took out some pen and paper and started deriving th formulae. After a while I had a plan and I wrote a nice simple makeshift solution. It worked but in my head all sorts of great ideas popped up. What if the grid was in 3D and could be rotated? Would it be possible not to just align objects but construct an entire coordinate system out of it? What if the origin of the grid was not the origin of the world but any point in space? Would it be possible to have more than one grid in the scene? How about entirely different grid shapes than just squares? And if all that was possible, wouldn't be possible to use the grid for more than just aliging? Could the grid be used for actual gameplay?
The idea at the time was to get the makeshift solution polished up a bit and then give it away for free and ask for a small donation or sell if really cheaply. This idea was humble, if you want to be nice, or stupid, if you want to be realistic. Essentially, it wouldn't have made any user happy nor would it have made me money. No one would win. Fortunately the Asset Store submission got lost somehow and remembering the awful drawings I had for the Asset Store pictures, it really was for the best.

This Time For Real
The lesson I leared was that if you want to do something do it either right or don't do it at all. People will remember a halfassed effort and you will never be able to shake it off. Instead I decided to get serious this time, I switched my language from JavaScript to C#, dug into the deepest depths of the Unity documentation and learned many new things along the way. At times it was infuriating, at times it was fantastic and at times it was plain boring. Nonetheless, if I had the chance to travel back in time I wouldn't do anything differently (except for some lessons I had to learn the hard way), the experience alone of crafting something on your own and working towards a goal is very rewarding. I don't think there was anything left from the first draft, and even if it was it is all gone by now. Good riddance.
If it had been just the coding part it would have been enough already. Being a one man team however, I also had to write the documentation, design a logo, create the Asset Store promotional material and write descriptions for the Store and the forum thread. I never learned anything about marketing, but I did work in retail, this is where my exerience came in handy. On the internet I can think all day about the description text, but when it comes to talking face to face with real people your brain has to act very quickly.

The First Release
If you were to ask me what the hardest part was, I would say finishing it. There comes a point when you have to draw the line and stop adding new features so you can iron out the remaining bugs and wrap up the lose ends. There were still some left after the release though, mainly the integration into Unity's interface, no cusom inspectors for the grid classes and the complete lack of rendering. I decided to tackle those as quickly as possible, for I was running out of time.

The 1.1.x Line
I had no idea how to do the rendering and at one point I was considering imitating Vectrosity's behaviour (after asking for permission of course). Anyone who owns Vectrosity and who has taken a look at the code will be blown away by all the work of the author, there was no way I could just rip out some parts and call it a day. Instead I decided to write my own rendering solution and offer Vectrosity support as an option, since I already had a license and the two looked like a perfect fit. Both solutions work in fundamentally different ways, so users can choose the one they like best. Yay for choice ^^
After getting rendering, the biggest missing feature, and Vectrosity support out I had two things to do: many small improvements like a custom rendering range or additional functions and of course hex grids. This was during the summer when I was busy studying for exams, so my work on Grid Framework slowed down to a crawl after the first few 1.1.x releases.

Version 1.2.x and hex grids
After the exams I was finally able to devote time to Grid Framework again. The hardest part about hex grids was not so much the math, although that wasn't easy either, but how many possibilities there are to do hex grids. I already discussed this topic a few months ago, but this was a real pain. It was clear I wouldn't write several classes, so I had to design my code to accommodate for all the cases. In the end the solution was not really hard, it was the journey there, I just couldn't find anything on the internet or in any book about how to do it. What really matters in the end though, is that I was able to deliver one class for all cases, fitting right with my design principles established in the first release.

The Future of Grid Framework
Well, that's it for last year, but what can you expect for 2013? First of all, I'm working on my own website, so far it has only been this blog and the forum thread, but I would like to give Grid Framework a proper web presence. I had to learn HTML and CSS from scratch, but the site is almost done, just a few finishing touches and it should be up soon.
Hex grids have the same feature set as rectangular grids, but there is more we can do with them, most notably more coordinate systems. Expect more updates for hex grids after the site has launched. There are also a few minor features I would like to get done all across Grid Framework, so I'll add them inbetween the more important releases.
Triangular grids and path finding are next on the priority list, I just haven't decided which one would be more important. Triangular grids sound easier, but path finding seems more useful. I'll have to think this over when the time comes.

Well, that's it for this time. Have a good year 2013 and thank you all for your support :)

2012/12/24

How to extend Grid Framework with your own methods

Let's say you just bought Grid Framework, wrote some game logic and now you want to reuse it. Wouldn't it be great if it was a class method in Grid Framework so you could simply call it with one line of code? Even better, what if you could have one method that has the same syntax for both rectangular and hexagonal grids but different implementation based on the type of grid, so you would have to write just one script for any type of grid? Luckily this is no problem in Unity thanks to extension methods and if you have the code, then wrapping it up into an extension method can de done in a few minutes. Take a look at my latest video tutorial:
Extension methods are only available in C#, but once you've written the method you can use it in any of Unity's scripting languages. Aside from keeping your code cleaner, extension methods have the advantage that if you need to make adjustments to your game logic you only need to do it in one place and every call of the method benefits from it.

2012/12/17

Hex Grid introduction video

I made a short video giving you an overview of hex grids, so you can see them right in action. I'll make a video on how to extend Grid Framework with your own methods yourself next,

2012/12/07

Grid Framework version 1.2.0 released

The wait is over, version 1.2.0 is out, bringing you the long promised hex grids. I'll soon make a video demonstrating the new grid, in the meantime let me explain it in words. My implementation brings you all the features you knew from rectangular grids, except on a hex grid, and both grids inherit from the same base class. This means the API for both is the same and you can write one script for both grids with little to no need to make special adjustments for differentgrid classes. Currently there is only one coordinate system and hex grids have "only" as much functionality as rectangular grids. I whish to improve upon this in the future.

Phew, this has really exhaused me. Often times I was wondering what I had gotten myself into and it was not uncommon for me to work beyond midnight, pondering above pencil-drawings, deriving formulae and thinking how to make everything work nice. The last stretch has been especially tiresome, getting the computer to do something is one thing, but then you start putting together the manual and you notice that the way it *how* it works doesn't feel right. It's those little thing no one notices when they are done right but everyone notices them when they are done wrong. What kept me pushing forward are you guys and your support. Many of you are silent, and that's fine, but I know you are there. Thank you.

Grid Framework version 1.2.0 submitted

Just a quick update, version 1.2.0 has been submitted. This is your last chance to buy the package for 15$, once it has been approved the price will be raised to 20$.