Starting Puzzle Balls I didn’t have the slightest idea what Unity is. “Game engine” didn’t really say anything to me.
What have I learned doing my first project in Unity?
1. Quick feedback is everything
Turned out, Unity gives you plenty of features, regarding code and non-code, all optimized for seeing your progress quickly.
Click-click and there’s a sphere on the screen.
Click-click and it has physics.
Click-click and it has velocity.
Type-type some C# code and the sphere starts with no velocity, but starts moving when the spacer bar hit!
Seeing some objects moving on the screen from day 1 was a driving force for this project. And that was a game-changer compared to my previous project.
That was much different from (American) Football Manager, written in TDD in pure Ruby. After 3 months or so all I could produce was a text file. And any types of graphics were outside any foreseeable future.
2. Specificity of ECS pattern
Unity is built around ECS pattern.
I highly recommend reading up about this before starting with Unity. I only learned this term like 2 months after the project started. If I had learned it earlier, the learning curve would have been more favorable for me.
In short, Unity allows you to spawn objects left and right, provided you don’t go much into detail about what is happening and when.
This results in chaotic execution flow, making all the code harder to reason about. Also, there’s just no clear entry point to the code execution. This is much different from what I experienced as a full-stack web developer, where the flow is pretty much straightforward.
Anyway, after some initial confusion, it works like a charm, especially first days. But it has its cost…
3. Unity gives but also takes something away – control
It’s a fair trade.
But as time goes on, you may want to have more influence on Unity entities, for various reasons:
- You want to understand the flow. Quick prototyping is great in ECS, but sooner than later a decent developer should start wondering about the internals.
- You want to write some unit tests. If you are like me, you have a strong commitment to automated tests and a test-first approach. You want to create loosely coupled objects in isolation, which in Unity isn’t the case out of the box.
- Improving code design and architecture. You want your code pieces to communicate. Normally in Unity, this is another “click-click” procedure. Literally, you drag-and-drop one script into another and make a dependency. Great in the beginning, pain in maintenance.
Those should be very important concerns for every developer. Those were very important concerns for me.
So, what if the time comes? How do you untangle the Unity lifecycle, how do you decouple components? Turns out you can’t (with Unity alone). Unity takes the control away from you and doesn’t expose much.
Kinda like React components in the pre-hooks era. They live in the runtime on their own. Only React gives you all the lifecycle methods you can imagine. Unity does not…
Fortunately, there are external tools for that job!
4. Extenject is your best friend
It is a Dependency Injection tool, and it’s done specifically for Unity.
Although DI is its selling point, it can do much more than that. In practice, Extenject addresses all the concerns mentioned above:
- It brings out the execution flow so that you have more vision and control over it.
- It makes unit tests of Unity entities much simpler.
- It makes the code design clearer, yet still integrated with Unity.
Extenject is a maintained version of it’s predecessor, Zenject. In Unity Asset Store there is no Zenject, only Extenject. Anyway, any learning resource for Zenject (which are plenty) applies to both.
5. Unity is mostly used by non-programmers
At least that’s the impression that an experienced developer like myself can get, based on questions and answers on the forums and SO.
People usually shirk code solutions and look for something that can be done by clicking.
Code design is a tabu – if it works, why structure it?
It wasn’t unusual for me to spot obvious mistakes and shortcomings in people’s code or screencasts.
Unit tests are less normal than in web dev.
Resources on code design are lacking. There are good blogs like this one, the author is very deep yet detailed about a particular, narrow topic. But I haven’t found a good resource about how to start with Unity with a solid programming background, addressing common concerns, etc. I start seeing a niche here.
There aren’t good practices on how to structure your code. Or how to debounce a function. But you can easily add bones to an image so that it’s easy to animate.
6. Unity and Mac – not a good pair
Developing Unity project on Mac is not impossible. But it is pain.
Good luck finding other devs not working on Visual Studio. And by the way, I learned the hard way that Visual Studio for Mac is a joke.
I actually started feeling (for the first time in my life!) the lack of a proper workstation. A nice PC with Windows + a bunch of monitors would have been nice.
Not complaining, I obviously know who is in charge of C# and Visual Studio and what is their attitude to Apple.
My personal inconvenience is one thing. Unfortunately, the problem is deeper.
All the Unity people around there seem to use Visual Studio. They automatically assume that Unity development = using Visual Studio.
In consequence, many tutorials, forums, troubleshoots, etc. show how to solve a particular problem via Visual Studio.
People don’t know (or don’t share?) how to solve the problems directly on a project, only how to do the solution in a particular IDE.
Extremely bad design!