Unity Performance Optimization Tips

Published January 19, 2017 by Vidyasagar M, posted by VidyasagarMSC
Do you see issues with this article? Let us know.
Advertisement

Optimization should be considered even before starting the game. In fact even before choosing your assets more importantly 3D Meshes. Let me provide you some important tips which I collated after reading some books, web links and going through videos.

Tip # 1: Minimize Vertex Count

The Unity renderer has lots of techniques and optimizations built in to draw meshes quickly and efficiently across different devices, but you can really help that renderer do its work even more efficiently if you reduce the vertices in your meshes so far as possible.

Note that the Stats panel displays the number of triangles and vertices currently being rendered - and not the total number of vertices and triangles actually in the scene, which will often be more because the camera usually does not see the entire scene at once.

Tip #2 Minimize Materials

Unity allows you to create as many materials as you need for your meshes and objects and you can even assign multiple materials to the same mesh. Using materials comes at a performance cost, however, in terms of draw calls and draw calls are relatively expensive on any platform.

Try to avoid using multiple textures for a single mesh; instead, share the same image for all parts. Using Atlas Textures for 2D games, Objects could share the same texture and material.

Sharing materials in this way between objects allows the Unity renderer to internally batch those objects into the same draw call, and this typically improves on performance than if those objects had been drawn in separate calls. Refer Texture2D.PackTextures.

Tip #3 Use Per-Platform Texture Settings

If you select a texture in the Unity Project Panel and examine its settings in the Object Inspector, you'll see its options regarding size and compression are customizable on a per-platform basis. This means you can adjust the size and compression of textures differently for each target platform: Windows, Mac, Android, iOS, and so on.

The trick is to try and build your game so that optimization is possible without being too noticeable, using tricks such as reducing the amount of alpha transparency in textures so that you can use a non-alpha compression system, system, or using texture atlases to put everything onto a single texture rather than several separate ones.

gtr_performance_optimization_service.jpg

Scripting Optimization

Tip # 4 -Cache Components and Objects

One of the most common C# scripted statements when working with the Unity API is transform.

This statement (and others like it, such as audio) accesses a C# property, which returns a reference to the transform component of an object. From this, you can directly set the GameObject's position, orientation, and scale.

However, accessing the transform component in this way indirectly calls on additional functionality that can have an accumulative impact on performance, if called enough times in events, such as Update or OnGUI. You can optimize such expressions from the outset, however, by using Object Caching. That is, by getting a reference to the component or object, and by storing it in a local variable. An example of object caching at work.


void Awake() 
{ 
	// Cache Transform (MyTransform is a class variable) 
  	MyTransform = transform; 
}

void Update()
{
  	// Update position using cached transform 
  	MyTransform.localPosition = MyPosition; 
} 

Tip #5: Avoid Using Update

This is not a good idea since Unity has to invoke the update function and you are performing work every frame. A better solution is to disabling the behaviour until the player comes closer.

There are 3 ways to do this:

Use OnBecameVisible and OnBecameInvisible

These call backs are tied into the rendering system. As soon as any camera can see the object, OnBecameVisible will be called, when no camera sees it anymore OnBecameInvisible will be called. This is useful in some cases, but often for AI it is not useful because enemies would become disabled as soon as you turn the camera away from them.

 


using UnityEngine;
using System.Collections;

public class example : MonoBehaviour
{ 
	void OnBecameVisible() { enabled = true; } 
	void OnBecameInvisible() { enabled = false; } 
} 

Use triggers

A simple sphere trigger can work wonders though. You get OnTriggerEnter/Exit calls when exiting the sphere of influence you want

 


using UnityEngine; 
using System.Collections; 

public class example : MonoBehaviour
{ 
  	void OnTriggerEnter(Collider c)
    { 
      	if (c.CompareTag("Player")) 
          	enabled = true; 
    } 
  
  	void OnTriggerExit(Collider c) 
    { 
      	if (c.CompareTag("Player")) 
          	enabled = false; 
    } 
} 

Use Coroutines

The problem with Update calls is that they happen every frame. Quite possibly checking the distance to the player could be performed only every 5 seconds. This would save a lot of processing power.

Tip #6 - Avoid OnGUI and the GUI class

The OnGUI function and the GUI class can be two of the biggest drains on performance, especially for mobile games. OnGUI is expensive primarily because it's called multiple times per frame.

This means you almost never use it to perform game-logic or core functionality--the purpose of OnGUI is exclusively for drawing GUI elements. The GUI class can work well for smaller and simpler interfaces, but should really be avoided for complex interfaces with many interactive elements, such as inventories, statistic panels, mini-maps, option screens, and type-in dialogs.

I've almost never seen high-performance come from the default GUI class when implementing more feature-filled GUIs. To implement these, Unity offers very little native support. There are two main and popular solutions to this: either a custom solution is developed, using Atlas Textures and, or a third-party add-on must be purchased, such as NGUI or EZGUI.

Tip #7--Use Object Pooling

Imagine this: the player character is firing a fast-reload weapon (such as a chain gun) and each shot spawns a new bullet into the level. The fire-rate for this weapon means that two bullets are generated per second. Assuming the bullet object is created in the project as a prefab, how should the bullet generation be scripted?

One way to handle this is to call the Instantiate function for each bullet, whenever the gun is being fired. This method might be called "Dynamic Object Creation." However, there's another method: at level start-up you could generate a large batch of bullets (perhaps 30), and store them off-screen.

Then, whenever the player fires a weapon, you would continually show, hide, and move these pre-generated bullets, as required, to simulate bullets being spawned, as opposed to really spawning them.

This latter method is known as Object Pooling. In general, Object Pooling is to be preferred over Dynamic Object Creation because it avoids the performance issues that sometimes comes from dynamic memory allocation, especially on mobile operating systems.

The upshot of this is: avoid instantiating and destroying objects dynamically. Instead: generate objects at level start-up, and then show and hide as required to simulate object destruction and creation.

Profiler

What Is the Profiler? The profiler is an advanced tool for finding out all kinds of important information about your system resources during playback. It can be used to profile CPU, rendering.memory, audio, and physics so that you can find ways to optimize toward a better-performing game.

Simple Checklist to make Your Game Faster

  • Use skyboxes to "fake" distant geometry.
  • Learn benefits of Occlusion Culling and use it to reduce amount of visible geometry and draw-calls in case of complex static scenes with lots of occlusion. Plan your levels to benefit from occlusion culling.
  • Do not use fog when it is not necessary.
  • Use compressed texture formats when possible, otherwise prefer 16bit textures over 32bit.
  • Do not use dynamic lights when it is not necessary - choose to bake lighting instead.
  • Do not use Pixel Lights when it is not necessary - choose to have only a single (preferably directional) pixel light affecting your geometry.
  • Set Static property on a non-moving objects to allow internal optimizations like static batching.
  • Keep the number of different materials per scene low - share as many materials between different objects as possible.
  • If you're using built-in shaders, pick ones from Mobile or Unlit category. They work on non-mobile platforms as well; but are simplified and approximated versions of the more complex shaders.
  • Keep vertex count below 200K..3M per frame when targetting PCs, depending on the target GPU
  • Use pixel shaders or texture combiners to mix several textures instead of a multi-pass approach.
  • If writing custom shaders, always use smallest possible floating point format:
    • fixed/lowp- for colors, lighting information and normals,
    • half/mediump - for texture UV coordinates,
    • float/highp - avoid in pixel shaders, fine to use in vertex shader for position calculations.
  • Minimize use of complex mathematical operations such as pow, sin, cos etc. in pixel shaders.
  • Choose to use less textures per fragment.

Conclusion

Performance Optimization is the most important aspect of your game which you should consider even before starting your game design.These are a few tips to consider before choosing your meshes,textures and other assets for your game.

The same is applicable to 2D game development alsowhere you use sprites with textures.These tips also are not limited to Unity3D game engine alone and can be considered for any game engine or framework.

Cancel Save
1 Likes 0 Comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!

Featured Tutorial

Optimization should be considered even before starting the game. In fact even before choosing your assets more importantly 3D Meshes. Let me provide you some important tips which I collated after reading some books, web links and going through videos.

Advertisement

Other Tutorials by VidyasagarMSC

VidyasagarMSC has not posted any other tutorials. Encourage them to write more!
Advertisement