Hex grid drawing - finally!

I have finished the drawing part for hex grids. As I mentioned before, there are many ways to draw hex grids and I want to cover as many of them as possible. Let's count all the possibilities that work now.
There are three plains to draw on, the XY-, XZ- and YZ-plain. In each case you have the choice of having pointy sides or flat sides, those are two possibilities. Every second line is offset upwards, so you can either draw those offsets or keep the grid compact, so two more choices. Each grid can begin with an offset colum or not (two more) and end with an offset column or not (again, two more). That's a total of 3 x 2 x 2 x 4 = 48 possibilities! On top of that no line should be calculated more than once, or else it would be drawn twice. That may seem trivial, but if your lines are semi-transparent the difference between lines drawn once and twice can be seen.
Needless to say I don't want to write and maintain 48 similar algorithms, everything has to be handled automatically by one single function. Eventually I got it, it works with any of those possibilities. I've prepared four variations of the same grid to give you an idea. The upper ones are the pointy sides, the lower ones are the flat sides. The left ones are fully drawn, the right ones are compact.
There are also other ways to draw a hex grid, as a rhomb, a triangle or a big hexagon made from smaller hexagons. I will do them after I have the scripting functionality done, drawing is independent from the other calculations.


swap variables in Unity

I've decided to go with one HexGrid class and provide enough options. To do this I will need to swap around variables so I can use the same formulae for different cases. I could write the swapping part where it is needed, but then I'd be writing the same thing several times (which is a bad thing to do). Wouldn't it be better if there was some sort of swapping function? Could that function work for any type of variable? Could it work without needing to reassign variables again? Yes to all of that:
 void Swap<T>(ref T a, ref T b){  
      T t = b; b = a; a = t;  
It works the usual way, you create a temporary variable, assign one variable to it, then assign the second to the first and the temporary to the second. The T stands for the type, this is a generic function, meaning you can use it for any type you want. You can swap int, float or even something crazy like Collider or something usermade. The ref means that the changes done to the variables in the function are reflected right back. Usually a function "copies" the values passed and leaves the original variables untouched. To use the code you would write something like
 int x = 1, y =2;  
 Swap<int>(ref x, ref y);  
There are some tricks floating around on the internet without the use of a temporary variable and using math tricks instead, don't use those. At best your code just gets ugly, at worst you even get worse performance. Also, you are limiting yourself to numbers only, whereas this Swap function works for anything. Hooray for generics!


The current roadblock

It has been over a week since my last post, so I might as well explain what's going on. As I finished rendering I had tightened up all loose ends that were left, I consider Grid Framework to be complete for rectangular grids. You can perform all the common calculations, debug things and visualize the grid properly, either using simple lines or even Vectrosity. This is just the first step though. Hex grids are very popular for games for various reasons, so it makes perfect sense to do them next, right? Well, here is where the problem starts.

See, while making Grid Framework there are several challenges I need to face (let's just ignore things like documentation or presentation for now). Obviously I need to code the whole thing. I also need to figure out the math for how to even do these calculations. None of those are really any big secrets, the math has been there for centuries and the coding part is just turning verbose instructions into C# code. It's a pretty straight-forward process, more or less, once you figured out what to do and how to do it. And that's where the current challenge lies.

Rectangular grids are relatively simple. Being in 3D and able to rotate and translate and having individual spacing made them more complicated, but it was still the same basic formulae, just more expanded. Hex grids are not as easy, simply because there is more you can do with them. This leaves me with some really nasty design decision.
When writing an extension I need to keep in mind that it will be used by lots of different people who might have different ideas about what a hex grid should work like. Some might want to fit a grid inside a rectangle, like in battle for Wesnoth, others might want one big hexagon made of smaller hexagons, like in Settlers of Catan. I cannot just pick one and tell the others to convert their game to the other type. This also raises the question of coordinates. A rectangular grid is just a standard cartesian coordinate system with some stretching and squeezing. I can even have fractions of a coordinate to give a precise position. If I fit a hex grid inside a rectangular grid, can I still have fractions? Do I even want such a feature? What should the coordinates represent, vertices or faces? What about the pointy side of a hexagon, is it one unit or just half a unit? Speaking of which, how does everything change if I want the tops to be pointy instead of the sides? Where should the origin lie? How many axes should even be there? (don't laugh, once concept uses four dimensions)

All of these questions can be answered, that is not the problem. The problem lies in answering them all in a way that is clean to implement, clean to maintain and clean for the end user to use. Should I make different hex grid classes, which would be easier to code, but would mean more code to maintain and more API for the user? I would like to just start coding and see what happens, but these questions need to be answered first, or the code will explode right in my face. I don't know how long it will take, but I'm working on it.


Version 1.1.3 released

You know, sometimes I look at something and wonder "what kind of idiot designed this!?", only this time I was the idiot. Let's say you wanted to render a simple 3x3 grid and you wanted the origin to be in the lower left corner. Well, you simply couldn't do that, not until now:
Instead of using the size you can now specify your own range, the only limitation is that From has to be less than To obviously. As a nice extra touch those two fields will only appear when you you choose to use custom range, otherwise they will be hidden and won't clutter your view.

Important note about updating: Until now you got one folder and had to move the Plugins folder to the root of your project view manually. This is no longer the case, Grid Framework should now place all files in their proper directory without you having to do anything. If you have an older version of Grid Framework and get errors or warnings please delete all your old Grid Framework files. This is the last time you will have to do anything manually.
I am sorry for this inconvenience, but there is some common misinformation that all assets must be in one folder. The fact is you can send your entire "Assets" folder and the Asset Store Tools will be ignored.


Version 1.1.2 released

It's up, version 1.1.2 brings Vectrosity support, better documentation and integrates Grid Framework into the menu bar. From now on you will never again have to drag scripts manually from the Plugins folder onto objects when using Grid Framework.
If you want to try the Vectrosity examples please uncomment the scripts. I had them commented so they wouldn't give errors to customers who don't have Vectrosity installed.


Vectrosity progress

Well, it's pretty much done, you can now get a set of Vector3 points for use with Vectrosity from just one line of code. I played a bit with Vectrosity to make an example scene and this is what it looks like:
(yes, I am a sucker for laser lines)
The green grid just hangs there and rotates, the red grid bounces around (using Unity's physics engine), the yellow grid resizes itself all the time and the colourful grid changes the colours of its lines randomly. The "missing" lines in the last grid lines are not a bug, they are sill there but coloured black.

I expect version 1.1.2 to be the last feature update before adding Hex Grids, so I want to wrap up all the loose ends I might still have left. In particular I want to integrate the components into Unity's main interface, no more dragging scripts onto GameObjects.


line width for rendering

I just submitted version 1.1.1 (update: has been approved) which lets you set the width of the rendered line in the inspector. Here is an example, obviously it's over the top, but you can set the width to anything you like.

Now I just need to provide a nice function to pass rendering points to Vectrosity. I'm sure those of you who own a Vectrosity license would like to be able to combine the best of both. I promise when I'm done it will be the last time you'll see me talk about rendering for a while.


Version 1.1.0 out now - rendering included

Unity just approved version 1.1.0, which includes the new inspector panel and the rendering setup. Now you can see your grid in the finished game, no pro license or any other addon needed.


a new inspector

Well, I wanted to do this sooner or later anyway, so I made a custom editor for the rectangluar grid. Before this I was using the default inspector panel:
So, why am I doing GUI stuff if I'm supposed to work on the rendering? Well, as I said I need to clean up the code, which involves looping through two custom classes of mine, ColorVector3 and BoolVector3. If you used Vector3 you know you can access values using something like myVector.x, but you can also use an index instead: myVector[0]
I wanted to have both in my two classes so I could loop through them in one go rather than write a special case for each entry and provide an intuitive syntax for users. The solution was using an indexer, setters and getters. They all work fine in code, but I cannot get getters and setter to display in the inspector and manipulating the entries directly could break things. The solution was writing my own inspector from scratch.
Aside from now being able to provide a safe and clean way to set colors and toggle axes the new inspector looks cleaner and the attributes are sorted in a way that makes more sense, rather than the way the class is built. I'm still not satisfied with some parts, the axis colours don't have labels and the the hide axis flags should be on the same line, like the Vector3 field. However, if I force them on one line or add labels to the coulour flieds the space for the labels is so large that the controls start overlapping, so it looks even worse than before.

Anyway, it does look better now and gives me the code improvements I need for clean rendering, so all in all it's a success.


grid rendering progress

Take a look at this:
What's so special? Look at the upper right corner, gizmos are turned off. This is a grid rendered at runtime that would be visible in a released game. There are still some things to care take of first: For one, the grid needs to get rendered every frame, which is not a big deal when using the GL class, but a Vectrosity-like approach where a mesh is built only once and then drawn once until it updates would be pretty neat. Also, the GL class doesn't let you set the width of lines, I could draw quads instead, but those are only thick if you look directly at them, otherwise they get thinner until they become invisble (in other words, they are flat). Lines are always the same, no matter the angle or distance, which could be exactly what you want or not. Maybe I could include some way for users to use Vectrosity easily if they have a license? In any case, I need to finish this first. The code is still very messy, being in large parts copy-pasted from the drawing code (which was kind of messy itself) and copy-pasting code is a sure way to have your project explode right in your face. I'll need to write a method to return a nice list of points that both drawing and rendering can use.


version 1.0.1

If you tried debugging the functions FindNearestFace() or FindNearestBox() you might have noticed that the cubes drawn didn't have the same rotation as the grid. While it didn't change anything about the returned value (only the centre of the cube mattered), it looked ugly. I've submitted a small update that fixes the rotation:
The update should get approved soon.


grid-based game logic

Another video tutorial, howing how to use grid-based game logic in a puzzle game. This is the tutorial for the lights-out game I mentioned before and which has been included with the package.
This tutorial is written in C# because it uses delegates and events. The reason why is so that no single tile needs to know about the other tiles, making this code extremely flexible, you culd even change your scene during runtime. If you don't know about delegates and events I really recommend you to check out prime31studios' video. Their video series really got me into C# development.
To give you the basic idea, events and delegates mean that somewhere somehow something happens and some other objects react to that. The object that triggered the event itself has no idea who (if anyone) is listening and how they will resond. For example you could have an RPG where when you draw your sword it makes villagers run away and guards draw their own weapons. Your hero would not need to know how many villagers and guards (if any) are around, he just needs to fire the event and all listeners will react accordingly.



Grid Framework has been approved and is fom now available on the Unity Asset Store for 15$
This is the price for the initial release, it will go up as the amount of features increases, but all existing customers will get all updates for free. Please feel free to visit the support thread and drop me a line if you have any questions or suggestions. Once the first wave of purchases has passed and if there are no issues I will start working on either hex grids or grid rendering, whichever you guys might find more important.

And to think that is has already been four months since I started this blog... the framework has gone quite a long way from a quick&dirty solution I rolled up in two days to something I can proudly announce. I am looking forward to an even brighter future for Grid Framework.