Controls, architecture, events galore…and worms
It’s been a few weeks since the demo release, so it’s high time I think for an update on what I’ve been working on since then!
As I’ve mentioned in the past, I’m still not entirely happy with the construction interface. One aspect of this is the way you rotate the selected part while aligning it to another part prior to attaching it. The current method of using the mouse to rotate around various axes is OK once you get used to it, but I worry that it’s a bit awkward to use, particularly for people new to the game.
So I tried prototyping a system where you use a key to cycle between the available orientations. The trouble is, there can be up to 24 possible orientations (e.g. 6 sides on a block, and 4 orientations per side, so 6 x 4 in total). I found this to be way too many to cycle between and was rather frustrating to use.
So I tried breaking it up into cycling between alignment axes (e.g. the 6 sides on a block) with one key, and cycling between the 4 possible orientations around the current alignment axis with another key. This was a bit better than using just one key, but still didn’t feel good to me. Perhaps this was because it was sometimes hard to tell which way the part had just rotated, or which way it was about to rotate on the next cycle.
I’m not sure that these ideas offer much, if any, improvement over the current mouse based method of rotating. Oh well, another failure! I guess you have to try these things, but I’m gonna leave this for now.
In order to keep the different code modules in GearBlocks decoupled from each other, I used messages (i.e. Unity’s SendMessage) to communicate between them. I wasn’t that happy with the way SendMessage uses a string lookup for the method name though – not very efficient, and there’s the possibility for name mismatches.
So I switched all of these messages over to use Unity’s event system. Events are now specified in interfaces that derive from IEventSystemHandler, and any code that needs to receive a particular event implements the relevant interface. To send an event to a game object, I use Unity’s ExecuteEvents helper functions. I created a system that multiple game objects can register themselves with to receive a particular event, to allow for efficient event broadcasting.
Not to be confused with the event system, Unity also has something called UnityEvents. These are great for when you want to hook up event handlers to events in a scene or prefab, rather than via code. I found these perfect for my UI code, so I switched this code over from using C# events to instead use UnityEvents.
The GearBlocks code was long overdue for some reorganisation, in particular I wanted to divide all the modules up into relevant namespaces. This is really valuable because it can highlight bad or unexpected code dependencies, and helps enforce a clear code hierarchy. Once I did this I found one or two suspect dependencies that I had to fix, but nothing too bad fortunately. It definitely feels better to have the code nicely organised now!
Finally, last week I implemented worm gears in the game. Happily, my plan for how to set up the physics constraints for this worked out first time! The implementation still needs one or two tweaks, but I’m pleased with how it turned out. As part of this effort I also simplified the existing gear engagement code somewhat, which should make it slightly more efficient.