2013/02/28

Grid Framework version 1.2.3 released

This update brings you two new features, both were suggested by customers. The first one is the ability to set a separate set of colours for rendering instead of using the same colours as for drawing. Let's say you want a barely visible grid in the game but a clearly visible grid in the editor. Until now you either had had to have two grids or use a script to change the colours once the game starts. Both options worked fine but required more work than needed, now you can do it out of the box. Of course it is entirely optional, so if you don't set anything you will be using the same colours for rendering and drawing.
The other new feature is relative size. Usually the size and the renderFrom/renderTo vectors were interpreted as absolute world unit lengths. I did this intentionally so the grid's size would be independent from its spacing (or radius and depth for hex grids). Of course not everyone is concerned about that sort of thing, some people would simply like to say "make my grid this many blocks tall" instead of having to multiply the desired size with the spacing. Turning on relative size now does exactly that for you. Here is a visual example where the values are interpreted as absolute (left) and relative (right) length:

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.