There are as many different ways to optimize code as there are reasons for performance problems. In general, it is strongly recommended that developers closely profile their applications before attempting to apply CPU optimizations. However, there are several simple CPU optimizations that are universally applicable.
Unity does not use string names to address Animator, Material and ShaderA program that runs on the GPU. More info
See in Glossary properties internally. For speed, all property names are hashed into property IDs, and it is these IDs that are actually used to address the properties.
Therefore, whenever using a Set or Get method on an Animator, Material or Shader, use the integer-valued method instead of the string-valued methods. The string methods simply perform string hashing and then forward the hashed ID to the integer-valued methods.
The property IDs created from string hashes are deterministic over the course of a single run. The simplest way to use them is to declare a static read-only integer variable for each property name, and use the integer variable in place of the string. These are automatically initialized during startup with no further initialization code needed.
The appropriate APIs are Animator.StringToHash for Animator property names, and Shader.PropertyToID for Material & Shader property names.
In Unity 5.3 and onwards, non-allocating versions of all Physics query APIs have been introduced. Replace RaycastAll calls with RaycastNonAlloc, SphereCastAll calls with SphereCastNonAlloc, and so on. For 2D applications, there are also non-allocating versions of all Physics2D query APIs.
The Mono and IL2CPPA Unity-developed scripting back-end which you can use as an alternative to Mono when building projects for some platforms. More info
See in Glossary runtimes treat instances of classes that derive from UnityEngine.Object in a specific way. Invoking methods on the instances actually calls into engine code, which must perform lookups and validations to convert the script references to the native references. While small, the cost of comparing a variable of this type to null is much more expensive than a comparison against a purely C# class. For this reason, avoid these null comparisons in tight loops or in code that runs every frame.
For vector and quaternionUnity’s standard way of representing rotations as data. When writing code that deals with rotations, you should usually use the Quaternion class and its methods. More info
See in Glossary math that is located in tight loops, remember that integer math is faster than floating-point math, and floating-point math is faster than vector, matrix or quaternion math.
Therefore, whenever commutative or associative arithmetic allows, attempt to minimize the cost of individual mathematical operations:
Vector3 x;
int a, b;
// Less efficient: results in two vector multiplications
Vector3 slow = a * x * b;
// More efficient: one integer mult, one vector mult
Vector3 fast = a * b * x;
It is common for applications that must convert between HTML-formatted color strings (#RRGGBBAA
) and Unity’s native Color
and Color32
structures to use a script from the Unify Community. This script was both slow and caused extensive memory allocation due to string manipulation.
As of Unity 5, there is a built-in ColorUtility API that performs these conversions efficiently. Usage of the built-in API should be preferred.
It is a general best practice to eliminate all usage of GameObject.Find
and Object.FindObjectOfType
in production code. As these APIs require Unity to iterate over all GameObjectsThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
See in Glossary and Components in memory, they rapidly become non-performant as the scope of a project grows.
An exception to the above rule can be made in accessors for singleton objects. A global manager object often exposes an “instance” property, and often has a FindObjectOfType
call in the getter to detect pre-existing instances of the singleton:
class SomeSingleton {
private SomeSingleton _instance;
public SomeSingleton Instance {
get {
if(_instance == null) {
_instance =
FindObjectOfType<SomeSingleton>();
}
if(_instance == null) {
_instance = CreateSomeSingleton();
}
return _instance;
}
}
}
While this pattern is generally acceptable, it is important to examine the code and ensure that the accessor is be called in ScenesA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary where the singleton object does not exist. If the getter does not automatically create an instance of a missing singleton, it is very common to discover that code looking for the singleton results in repeated calls to FindObjectOfType
(often multiple times per frame) and creates an undesirable drain on performance.
The UnityEngine.Debug
logging APIs are not stripped from non-development builds, and do write to log files if called. As most developers do not intend to write debug information in non-development builds, it is recommended to wrap development-only logging calls in custom methods, like so:
public static class Logger {
[Conditional("ENABLE_LOGS")]
public static void Debug(string logMsg) {
UnityEngine.Debug.Log(logMsg);
}
}
By decorating these methods with the [Conditional] attribute, the define or defines used by the Conditional attribute determine whether the decorated method is included in the compiled source.
If none of the defines passed to the Conditional attribute are defined, then the decorated method and all calls to the decorated method are compiled out. The effect is identical to what would happen if the method and all calls to the method were wrapped in #if … #endif
preprocessor blocks.
For more information on the Conditional
attribute, see the MSDN website: msdn.microsoft.com.
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.
When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer.
More information
These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages. If you do not allow these cookies then some or all of these services may not function properly.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore anonymous. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance.
These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites. They do not store directly personal information, but are based on uniquely identifying your browser and internet device. If you do not allow these cookies, you will experience less targeted advertising. Some 3rd party video providers do not allow video views without targeting cookies. If you are experiencing difficulty viewing a video, you will need to set your cookie preferences for targeting to yes if you wish to view videos from these providers. Unity does not control this.
These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information.