Esteban Ibarra

Nov 1, 2021

3 min read

Basics of Optimization in Unity

Yesterday's example should show why it’s important to cache your coroutines, but it’s important to cache variables as well.

The importance of caching GetComponent:

GetComponent does exactly what it says, it commits Unity to perform an action requiring searching and allocating memory. If this is being done in Update, that search and allocation are being done 60 times a second! As in yesterday's example, if you create a variable to hold that GetComponent, it will already be available for Unity to use and save a significant amount of time!

New isn’t always better!

One must be careful when using the new keyword as it usually creates a class that gets placed on the heap and becomes a candidate for garbage collection, unlike structs that get placed on a stack and are not garbage collected. Structs are actually a lightweight version of classes and you can learn more about them here.

Oftentimes, when we’re trying to move a gameObject in a direction, we use a new Vector3, while a Vector3 is a struct and doesn’t incur any garbage collection, it’s still a bit more optimal to cache a Vector3 into a variable, modify it, and then assign it back to the transform so you just change 1 variable instead of potentially creating a constant flow of new Vector3s.

Caching is especially important with classes like GameObjects. When you create a new gameObject, always try to cache it and object pool if possible. Caching it alone will save a lot of memory.

Precise PinPointing Pesky Performance Problems with Profiler!

You can create special profiler labels in your code so you can see the direct impact of that code segment! Remember you’ll have to use UnityEngine.Profiler namespace!

Use Visual Studio to check if something is a class or struct

Pressing F12 will tell you if a command is a class or a struct. If it’s a class, you’ll know if you’ll need to cache it.

Cache those yield returns!

When testing between a regular return and one with a cached WaitForSecond() method, the regular one used 3x more bytes than the cached! It’s always a good idea to cache your WaitForSeconds()!

Better RayCasting methods are available

Unity has optimized Raycasting and you can find them with the words NonAlloc. Ex: RaycastNonAlloc or SphereCastNonAlloc. Use them.

Camera.Main is a hog!

cache Camera.Main to save more memory.

Lists vs Arrays

Try to go with lists. They’re leaner and less memory intensive. Arrays must constantly be recreated from scratch when modified which could take up valuable processing power from other functions.

Structs vs Classes

Try to go with Structs as much as you can. They don’t get thrown on the heap and are extremely fast. A general rule of thumb is if a class has 5 or less variables and doesn’t need inheritance, go with the struct.