Mouse driven development
There is a decent amount of “mouse driven development.” Unity3d provides a fancy IDE-style interface to the game world where you can zoom around and interact with games in 3d space. You can click and drag objects around, as well as set position, rotation and size by typing in coordinates. A lot of layout within Unity3d is done this way and saved in binary files called “scenes.” The upside is that it’s very easy to visualize what’s going on in the world. Even in 2-dimensional interfaces, if there’s a question about whether one object is on top of another, it’s a simple matter to fly the camera out to the side and look. The downside of all this information being stored in a binary file is that changesets are much more difficult to read and review in source control, and even worse to try to merge across branches.
To deal with the impossibility of merging scenes, we started creating a lot of “prefabs,” which are prepackaged bits of a scene that can be instantiated through code. By separating out most of the layout code into distinct prefabs, we were able to work on multiple features at a time without stepping on each others’ toes. This solved most of our problems, but there were occasionally still times where we’d have to commit to the scene directly. In these cases, we would usually just announce to the whole team, “I’m about to commit to the scene!,” and tell everyone to leave it alone until the change was committed.
In addition to using prefabs, my team member Mike Judge came up with the idea of using a
PrefabRepository, an always-in-scene object that had a pointer to each of our prefabs so we could easily instantiate prefabs within the code. Each prefab object would also have an initializer so we could control how and when the prefabs were set up when injected into the scene.
No automated tests
There is not, to my knowledge, a practical way to do test-driven development in Unity3d. Part of the reason for this is that a non-trivial amount of the logic within Unity3d is stored in click-and-dragged associations within scenes, and not actually in code. Most of the professional development I’ve done in the past has involved test-driven development, or at least automated tests, to some degree.
Not writing tests on this project at times felt freeing in that I didn’t have to manage a whole separate set of code, but it did mean that we had to do a lot more manual testing to ensure we didn’t have regressions. (And sometimes regressions would still slip through the cracks.)
Although there are a couple of language options for working with Unity3d, by far the most common is C#. It’d been a while since I had last worked in a compiled language and it was interesting to see that a lot of the little mistakes that I was used to having a test framework catch would be caught by a compiler error instead.
One of the awesome selling points in Unity3d is the ability to build for multiple platforms with the same codebase. Unity3d can build to iOS, Android, and desktop platforms with just the click of a button! There were only a few cases where platform-specific code was necessary, and Unity3d provides convenient preprocessor directives to handle that logic.
Switching between iOS and Android build modes could be quite slow as Unity3d converted all the assets between formats, but the ability to have multiple platforms running on the same codebase more than made up for this.
All in all, Unity3d is a fun framework to work with, and provides a lot of benefits, with not too steep a learning curve. It has plenty of tools for dealing with 3d objects, cameras, & physics, and is a great framework for working with games or 3d simulations. Even with the downsides of “mouse driven development” and the lack of automated tests, the cross-platform capabilities more than make up for it, making Unity3d an excellent choice for game development.
This post originally appeared on the Substantial.com blog.