Basics of Optimization in Unity

Objective: Optimization Areas

When it comes to performance optimization, we have a few key topics that can make a massive difference to how your games perform.

Caching:

Ex.1

Let’s use the example in the image above. Looks pretty simple. Using GetComponent to get the Mesh Renderer, get it’s material then its Color and set it as a new color with randomly generated values. A simple line of code that just changes the color of a gameobject.

The problem here is that every frame Unity has to get the renderer and then the material and then the color. At 60FPS that means Unity has to get that component 60 times in one second before ever doing anything else.

Ex.2

Now we take the code in the above image. Still not perfect but now Unity has the renderer cached which means it can skip looking for that 60 times a second but we can still make this better. Right now Unity has the renderer but has to get the material. Why not cache that since we really don’t need the renderer itself but the material.

Ex.3

For the example, I’ve made 20 evenly spaced Cubes all with the initial GetComponent in the Update method. Let’s check the Profiler.

The above is using GetComponent in the Update method. Notice the Update method is creating 1.8K of Garbage Collection. (Code in image Ex.1)

By just Caching the MeshRenderer, we have reduced the same frame from 1.8K to 1.1K (Code in image Ex.2)

Here is where we see the biggest improvement. By Caching the Material itself, we have reduced the Garbage Collection from the Update method from 1.8K initially to only 86B, roughly 95% less.

New Objects:

When it comes to using the New keyword, we need to look a little deeper. When it comes to things like new Color or new Vector3, we don’t need to worry as these are Value types which are stored on the Stack and don’t cause Garbage Collection. On the other side we have Reference types. These are stored on the Heap and cause Garbage Collection allocation and wasting/using more memory. Reference types consist of Strings, Arrays and Classes.

That doesn’t mean that you should just create a load of new Value types as it may not create Garbage Collection but it can slow down game performance needlessly calling unnecessary new Value types. Instead you can create a struct and reuse it rather than multiple calls.

Coroutines:

We covered Coroutines in a previous post but we can review it here again briefly. It kind of goes well with the previous points. When using coroutines the use of yield returns can cause extra Garbage Collection and slow downs in performance. It’s best to cache a specific yield and then call the cached yield rather than creating new yields each call. For more on this, you can find my post here.

RayCasts:

Unity has made it easier to use RayCasts with better performance and with reduced Garbage Collection. This is done by using Non Allocation methods.

These can be used using the Physics.RayCastNonAlloc and Physics.SphereCastNonAlloc.

Also when using the Physics.Raycast usually we cast from Camera.Main. This is not performant. As shown in the previous points caching is your friend so cache the Camera.Main to save on memory usage as Camera is a class and therefore uses the Heap and creates more Garbage Collection Allocation.

Lists and Arrays:

When using Arrays, any action you perform that modifies it, causes the Array to be recreated. Lists are easier and more efficient to index and use. Lists can be cleared very easily using a List.clear. Use Lists instead of Arrays where possible.

Structs and Classes:

Structs don’t get added to the Heap and therefore don’t cause Garbage Collection. Be careful in usage though as there is a general rule of thumb that more than 5 variables use a Class and 5 or less use a Struct.

--

--

--

Developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

This happened to me: I allowed myself to believe I was the kind of person who

Serial Communication with Raspberry Pi Pico in Windows 10/11 via WSL

Why I learned to program

Hardware Development — Unit Testing and TTD

Python 3.8 Tips & Tricks Series - Application of Walrus Operator

Azure Certificate study guide 2020 (AZ900)

How to exit a Linux terminal while keeping long tasks running

The & Operator in Elixir

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Simon Leen

Simon Leen

Developer

More from Medium

Guidance of installing and usage of PostGIS on MacOS

Switching Character Control in Unity: Part II, Implementation

An animated gif. The window is split. On the left, a camera looks at a tank as it first moves towards the camera. The tank then stops and the turret begins to rotate left and right. The animation finishes with the turret elevating towards the camera. On the right, the same scene is shown from the perspective of a camera following the tank. After the tank finishes moving, the camera switches to one looking just over the turret and rotates with the turret as it first trains, then elevates.

Reverse Geocoding: Unity lambda expression

Adding proximity detection so enemies can ram player