5 tips every Unity developer should know
- select the contributor at the end of the page -
Unity error searching
If you are searching for the meaning or solution to an error message you received in Unity, you can easily find documentation about the specific error with a site search. Using Google, type "site:unity3d.com" followed by your error message. This searches for that error throughout all of Unity's site and resources, including their forms, tutorials, API documentation and knowledge base all at once.
If you ever find yourself with the problem of a consistent stutter in your frame rate, which is especially noticeable on a mobile build, the culprit is usually related to garbage collection (GC). GC attempts to reclaim memory occupied by objects that are no longer in use by the game. These are some of the common improvements and misuses which affect the GC.
GameObject instantiate and destroy
If you make frequent calls to instantiate and destroy throughout the lifetime of your game or app, this could affect the GC substantially. Try to create a pool of game objects at the start of your game, which you can then enable and disable throughout your game.
This might be used in tandem with interfacing to create a modular way of having your game objects interact with each other. A collection of components is generated and returned when GetComponents is called, and once this collection is no longer needed, it triggers the GC. Make sure you profile its use and determine if it's acceptable. You might have to develop another type of architecture to support your game object interaction that does not depend on GetComponents.
This is very common for C# developers. When you concatenate strings (“Hello” + “World”) you are creating a new string object. If you do this each frame, you are adding a good amount of unnecessary GC work when you could be caching or concatenating without +.
For those with Unity Pro, the profiler is an invaluable tool that allows you to detect memory leaks and garbage collection issues before your players do. You can run the profiler remotely with Android, iOS and web browsers which will test your game on the actual platform instead the editor. Also when you're testing remotely, the profiler won't affect performance like it does when it runs in the editor on the same machine, giving you more accurate data. Another great feature of the profiler is the ability to create code blocks that profile your scripts. You can place the start and finish profiler calls anywhere in your script and really start to dig deep into your game's or individual algorithm's performance. If you don't have Unity Pro, there are some third-party profilers in the Unity Asset Store that work with the free version.
As you become more experienced and comfortable with Unity and design principles, you eventually come to an important conclusion: The more generic a script is, the more it can be reused, making less duplicate code. And the less duplicate code and maintenance there is, the quicker one can roll out a new game. This is a great thing!
And if you develop in C#, once you learn about interfaces and abstract classes, your scripts can even get more generic. I would go as far as saying that with interfaces, you can achieve the most generic design of a single game's concern or responsibility.
Imagine having a player and an enemy game object in Unity each with their own scripts: a player script, and an enemy script. As these scripts are developed to handle the responsibility of dying for example, chances are it will start to smell of duplicate code. At this point you could create a separate death script with the duplicate code removed from both player and enemy. This is an improvement, but now you've created a dependency love triangle between these three scripts. We could instead create an IKillable or IDeath interface. This allows us to easily identify a single responsibility for the concept of dying. At this point we would create a PlayerDeath and EnemyDeath implementation.
But don't go crazy here either. When some developers first start to use interfaces, they tend to use them for almost every class. This could end up causing the same maintenance problems you were trying to fix, or it could just be a waste of time. There are certain rules and situations which call for the use of interfaces. Make sure you're aware of them.
Like a rocketship, test-driven development (TDD) for an individual or group that hasn't used it before is hard to get off the ground. But once you do, it's smooth sailing and the benefits begin to show themselves. It all begins with a test that defines the expected behavior of a feature. For example, say your character needs to spawn,at a specific position when they die. You write a test that spawns a player, kills them, then asserts that their position is near that spawn position (or that they collided with a spawn pad maybe). The key is that the spawn code to make the test pass does not exist when you write the test. You only add enough code to make your game compile, which could mean writing an empty spawn class and function. Once the test fails (since you do not have your spawn implementation), you can begin to work towards making it pass. Once the test passes, you can move on to the next feature.
TDD can get much more elaborate, but the benefits are clearly great. Imagine running dozens of tests which all light up green, meaning your game is working as expected. If you get advanced with continuous integration, you can commit your game to source control. This automatically builds, tests and deploys your game for you. Your team can even receive emails when your game passes or fails tests. The downside to TDD, which my team has experienced, has been in maintaining the tests. We wrote hundreds of tests for a third-party Unity testing system, which the developers gave up on. We ended up having to convert them over to Unity's official test tools, which has just recently been released, and it was time consuming.
Applying these tips when you're developing with Unity can save you time and frustration. Do you have any methods that make your Unity workflow easier? What are your must-know Unity tips and tricks?