Unity3D is an often recommended game making tool for beginners, the same way, how it was with Game Maker and a few others. I have been stumbling upon Unity3D for 3 months and I do have my strong opinions about that fact.
My thesis is that Unity3D may not be suited for beginners. Some people argue and say that it is a matter of taste. I disagree. In my opinion it's the matter of skills and facts. I would like to share some of my observations about Unity3D or actually how it can be misused. The following will not be an advanced take on the topic but rather a cover for beginning game developers who want to start with Unity.
I will present three areas of (lacking) skills which often kill projects in latter development:
- writing production-ready code - maintainable for a longer time than a month
- knowledge of differences between programming paradigms like OOP, GOC or ECS
- performance problems awareness - due to target hardwarde, language and architecture
Disclaimer: I do not want to look down on bugs because none of them really matter in a long term, also those do not define intereseting topics. What matters is architecture and concepts around it, and general usage of the software.
1. Prototype and done
First of all many folks try to make anything that works and after the moment it seems to work they consider the job as done. Later the project they lack professional programming skills where design of system architecture (code architecture) should come at first rather than prototyping some 3D boxes and basic interactions. Using prototype for real game code is probably worse motivation to go on.
Even if it's a prototype try to measure how long it will take to make the prototype only! If it's about full-time 2 months, I advice you to think a little before prototype process, especially if there's a huge chance of not throwing away the project.
Some basic architecture caveats caught by me are:
- time-based logic based on colliders instead of time flow. Due to how float number work it may happen that physical colliders may not collide. If you wait for some animation to end, then wait for it on some event and not OnTriggerEnter!
- logic based on some values that come from various components, instead of one script defining some behaviour which could be pulled of from there.
- writing same conditions in different places. When you want to change condition you have to change it in every place. Try to remember all of those - you won't.
- copying whole bunches of similar code, instead of parameterizing it. Copy-Paste method is wrong!
- thinking that Unity is not OOP so OOP should not be used. Stop! Bad thinking. Use OOP with GameObjects, then you will take the most advantage of coding in Unity.
- not using design patterns! For over 40 years there were so many much wiser people who have discovered some problems and solutions to them. The base concepts of OOP are cohesion and class role, use those, even in Unity.
By reducing those bad habits you can reduce your amount of new bugs per minute.
2. ECS/GOC vs OOP
Most of programmers who have never used GameObject-Component model or Entity Component Systems will have problems using Unity the first time. They usually try to compare it with Object Oriented Programming and fail under same OOP thinking.
Some basic concepts like Layers, Tags, Transforms, rendering system, physics system are already coded and work together quite good, so it's a huge relief for those who know only OOP. It's not an easy task to work out (design and code) those concepts into implementation, even if it looks obvious and simple. And to be honest - most of those built-in components are impossbile to be remade in Unity itself.
Unity also provides custom components called Script Components which are the only components that are written by (most of) Unity users. Not knowing how to organize them leads to misleading component naming and having too many dependencies between components. What happens next? It's hard to remove such components some - which is totally contrary for one of GOC/ECS premises. It's also hard to add new things.
To just list problems with scripts:
- unwanted or unexpected component dependencies
- object instantation timing
- no default place for holding logic data (you like to create managers?)...
- ... so creating some empty objects just to use some external libraries
- overusing tags and layers concept because there are just few
- overusing object hierarchy - every GameObejct have built-in Transform which is being multiplied by parent so it's so much of math
Just a few but probably there are many others.
EDIT: 2+ years later I wrote article: Why Entity Component Systems matter? Look into References in there to understand more about ECS.
3. Performance awareness
The third group of problematic users I can notice are those who don't know maths and those that are not aware of how computers, operating systems and applications cooperate together. Just to note some terms: processes, threads, coroutines (micro-threads), memory fragmentation or data caching on CPU (cache misses!).
Let's go back to Unity. For example many folks use Raycast, Colliders and overall physics everywhere. It happens to use them for logic. It works until you try to implement multiplayer and AI. But besides logic there are issues with performance on technically weak mobile devices. Not knowing what does raycasting can cause huge performance problems, especially on mobile devices which definetely are NOT PCs.
Maths knowledge is useful in every aspect - logics, network, physics and even graphics (actually, the most).
- For logics you may want to dynamically create some Artificial Neural Network. Of course you cannot do this, you have to precalculate and save it to load later.
- In network you could send too much data, it's rather simple to estimate it (even without calculator) how much data will be sent and received per minute.
- Physics will bite you when you overuse raycasting or too many physical objects on the scene interacting with each other.
- But here comes graphics. Adding too many lights, using dynamic lightning, best quality shadows and anti aliasing will consume your device totally.
Knowing maths still is not enough. Knowing how some systems work is also essential. For example, saving data can be done through so famous Serialization. Serialize too much things needed to be serialized in very short time and you will struggle. Standard .NET binary serialization takes too much of time and results are too big to send it over the network. It's good to understand how fast (or slow) is network and how different devices are working in there. But hey - there is Unity Network, right? Yeah, but still, you can make a bad use of it, e.g. using too much state-synchronized NetworkViews or overusing RPC (many times per frame etc.)
I'm a professional, let me work
OK, there are actually problems not related to skills but to software (Unity3D actually) itself. I'll name that by two words: collaboration and merge. It will be covered in one of next articles.
Unity3D is still pretty good software but it's a matter of time until one can properly and efficiently use it. I do not dislike Unity that much (yeah, there are some stupidities). My biggest dislike is the Unity popularity - it is being shown to beginners who don't know anything. Sure, they can create new prototypes but it's far away from making games.
I am pretty sure that taking into account the discussed three areas of skills at the beginning of game development adventure will bring a little chaos. That's why game programmers are often better at coding anything - because they struggled with similiar problems and managed to learn from it. If you want to be a great game programmer then know it - those problems will appear sooner or later - Unity or not.
And this happens a lot if you barely know what you're doing:
- Coming from a .Net programming background Unity's API feels like a horror-show - A frustrated rant that welcomes feedback and discussion!
- NetSerializer - nice simple and fast serializer which works good with Unity and .NET 2.0
- Entity Systems are the future of MMOG development - good start about ECS
- Artemis - fine ECS library for Java. Imagine Unity with this built-in.
- artemis-odb - even better Artemis!
- Emil "AngryAnt" Johansen talk: "Rapid Network- and AI-Ready Game Development in Unity" which covers some basic topics
- How to tidy your Unity code by putting it in a DLL - about code re-use
- The Last Line Effect - how Copy-Paste method can bring errors in code