Learn how to optimize your Unity project

This is a collection with links to sites where you can learn how to optimize your Unity project. You will learn how to optimize your code in Unity and other tips and tricks as well as best practices.

Unofficial sources


Official sources

Readable

  • Optimizing Graphics Performance. Simple guidelines for maximizing the speed of your game's graphical rendering.

  • Optimizing Script Performance. This page gives some general hints for improving script performance on iOS.

  • Good coding practices in Unity. The idea behind coding practices is that you keep in mind a set of guidelines when you write your code. These guidelines are often designed to keep your code maintainable, extensible, and readable, which in turn helps reduce the pain of refactoring.

  • Physics best practices. Best practices for when using physics in a game and some evidence to demonstrate why they should be used.

  • 10000 Update() calls.

  • Performance Optimization. Learn how to diagnose common performance problems and optimize your projects.

  • Occlusion Culling. Occlusion Culling is a feature that disables rendering of objects when they are not currently seen by the camera because they are obscured (occluded) by other objects.

  • Best Practices. Learn production tested best practices from our enterprise support engineers.

Watchable

  • Unite 2013 - Internal Unity Tips and Tricks. Tim Cooper, developer at Unity, gives a range of tips and tricks and explains why they work in the engine. Topics include smart data structure layout, property serialization and memory and graphics debugging.

  • Unite 2014 - Mobile performance poor man's tips and tricks. Tautvydas Žilys (Unity) on the most common pitfalls in perfornace how to actually know what is wrong in your game.

  • Unite 2014 - Big Android: Best Performance on the Most Devices. Orion Granatir (Intel) shows the best methods for reaching the highest possible FPS on the largest range of devices and looks at tools for low level profiling and optimization of the CPU and GPU (for ARM and x86).

  • Unite 2014 - The Hack Spectrum: Tips, Tricks and Hacks for Unity. Ryan Hipple of Schell Games shares a number of unconventional Unity tips, from polymorphic array serialization to stealing parts of the Unity editor UI.

  • Unite 2015 - Race The Sun Optimization. Flippfly goes into depth on their efforts to optimize Race The Sun for the Playstation Vita and other mobile platforms.

  • Unite 2015 - How we optimized our mobile game - Project Monsters. This talk covers a few techniques used to optimize a mobile game - Project Monsters.

  • Unite 2015 - Uncover Your Game's Power and Performance Profile. Maximizing the gaming experience on a mobile device requires more than innovative technology and gameplay. The gaming experience is equally affected by your game's ability to manage power consumption and avoid device heat ups as today's consumers expect always-on connectivity and all-day battery life from their mobile devices. These factors can impact a game's success by limiting game performance and creating an unplayable mobile experience. In this session, you'll learn how to improve power and thermal efficiency while achieving maximum performance for your Unity game on Android with Snapdragon Profiler, an exciting new profiling tool from Qualcomm Technologies, Inc.

  • Unite 2015 - Unity Maximus: Art Optimizations for Maximum Performance in Unity 5. Many platforms, like VR and mobile, place high demands on developers to meet acceptable framerates or else risk failure. Often, the art assets in a Unity project looks fantastic but no matter how optimized the codebase is, the build just doesn't meet the desired frame rate. Unoptimized art assets, including some art which may be purchased on the Asset Store, can seriously hinder performance on demanding platforms. In this session, we will highlight some red flags to lookout for in a variety of art asset types and identify key optimizations that can be implemented into your art pipeline to significantly increase performance on demanding platforms. Art asset types covered will include: 3D Models, Animations and Rigs, 2D Textures and Sprites, Materials and Shaders.

  • Unite Europe 2016 - Optimizing Mobile Applications. Making games run smoothly on low-end mobile hardware is challenging. Learn the best practices for analyzing mobile performance, reducing memory consumption and minimizing frame time, based on the experiences of the battle-hardened veterans from Unity's Enteprise Support team - Mark Harkness and Ian Dundore.

  • Unite 2016 - Let's Talk (Content) Optimization. This talk from Unity's Enterprise Support team focuses on real-world performance problems, analyzes their causes and discusses possible solutions to common pitfalls when loading content, displaying UIs or simply running a Unity game frame-to-frame.

  • Unite 2016 - Tools, Tricks and Technologies for Reaching Stutter Free 60 FPS in INSIDE. This talks is for Unity developers who are interested in the performance of continuously loading and unloading game assets during active gameplay without stutters. The developers of award-winning game INSIDE dive into the tools and technologies developed to achieve the above.

  • Unite 2016 - Multiplatform 3D Art Development for Indies. Lune Garcia Anaya (Feline Arts) shows how to get the best of each platform while maintaining the best art possible. Learn the basics of a 3D art pipeline for indie developers and how art impacts performance.

  • Unite 2016 - Shader Profiling and Optimization. This talk gives you an overview of how shaders fit into the Unity graphics pipeline and how to profile and optimize both vertex and fragment shaders. It features Unity's built in profiler and frame debugger, as well as a demo of how to use external tools such as Intel's GPA and Xcode to go even more in depth.

  • Unite 2012 - Performance Optimization Tips and Tricks for Unity.

  • Power Efficient Programing - Unite Europe 2015. How Funcom Increased Play Time in Lego Minifigures by 80%. Antoine Cohade (Gaming Application Engineer, Intel) shows a practical overview of power issues in gaming and how to boost the end user experience regardless of the platform's power constraints. He gives a practical example, developed in collaboration with Funcom, who created a power saving mode in Lego Minifigures. Their design resulted in an increased gaming time by more than 80% on tested laptops.

  • Mobile optimisation techniques - Unite Europe 2015. Tomislav Rakic Srdja Stetic-Kozic of Nordeus explain the optimization techniques that were used to bring Top Eleven 2015 to a wide range of devices. These techniques include custom serialization, tileable static batching, billboarded sprite batching, poor man's instancing for GLES2, and some others.

  • Graphics performance in The Supernauts: a Unite Nordic 2013 talk. A technical talk by Harri Hätinen (Gran Cru) on the challenges and solutions for creating and optimising Supernauts.

  • Game Connection Paris - Mathieu Muller on New Unity Features Seen Through the Profiler. Unity's Field Engineer Mathieu Muller about Unity 4.6 and Unity 5 features and their impact on performance.

  • Unite Europe 2017 - Performance optimization for beginners. In this introductory talk, you'll learn the basics of performance optimization and how to use Unity's profiling tools to help get your game running quickly and smoothly. You'll also learn some useful best practice optimization tips.

  • Unite Europe 2017 - Squeezing Unity: Tips for raising performance. Mark and Ian from Unity's Enterprise Support team run through performance best practices drawn from real-world problems. Learn the underlying architecture of Unity's core systems to better understand how to push Unity to its absolute limits.

  • Unite Europe 2017 - Practical guide to profiling tools in Unity. This practical guide shows you how to use Unity's set of profiling and debugging tools in order to eliminate common performance bottlenecks in your games. Learn the importance of mastering these tools to achieve smooth frame rates on mobile devices and in VR.

  • Unite Europe 2017 - The AAA graphics of Spellsouls: achieving 60FPS on mobile. Nordeus engineers retell the steps of their challenging journey to reach AAA console quality graphics on their new mobile game, Spellsouls: Duel of Legends. Hear how they created a PBR-like shader that runs on mobile, scaled the game across a wide range of devices (low-end toasters included), and about the various optimizations necessary to reach silky-smooth 60FPS.


Summary

(Note that this is not a summary of all links)

Code

  • Using localPosition is faster than using position. This is also true for localRotation

  • Reduce GetComponent calls. Using GetComponent or built-in component accessors can have a noticeable overhead. You can avoid this by getting a reference to the component once and assigning it to a variable (sometimes referred to as "caching" the reference): cachedComponent = GetComponent. This is also true for other Unity stuff, so caching transform is faster than not caching transform, and caching Time.deltaTime is faster than not caching Time.deltaTime

  • Vector3() * (5f * 4f) is faster than Vector3() * 5f * 4f

  • Caching List.Count is faster than not caching List.Count. But caching Array.Length is not faster than not caching Array.Length (Source)

  • Avoid vector math. position += 5f is slower than position.x += 5f, position.y += 5f, position.z += 5f

  • Avoid Mathf.Sqrt() or Vector3.magnitude which involves a square root. It's better to use the square distance Vector3.sqrMagnitude if you for example need to compare vectors.

  • Avoid foreach

  • Use object pooling if you need to create and destroy a lot of items (such as bullets or enemies)

  • Parenting an instantiated object immediately newObj = Instantiate(go, parent) is faster than doing it afterwards newObj.transform.parent = parent

  • If you for example have many rotating coins, it's faster to rotate one single coin and then use Graphics.DrawMesh() to draw the other coins by using the mesh of the first coin

  • OnBecameVisible and OnBecameInvisible is useful to avoid computations that are only necessary when the object is visible

  • Use Coroutines if you don't need to update every frame. You should also limit the amount of scripts that's using Update(), the fewer scripts that's calling Update() the better

  • Use structs instead of classes (Source)

  • Primitive colliders are faster than mesh colliders. And never move a static collider (a collider without a RigidBody). If you want to move it, then add a RigidBody to it and set it to kinematic

  • Combine nearby objects that have the same material into single meshes so they are drawn together. You can do this either manually or by using Unity's Draw call batching. But your Unity projects may also be slower because it makes culling less efficient and more objects affected by light, so you have to test what's good for you! Another alternative (since Unity 5.4) is to use GPU instancing.

  • Use deferred processing. If you are for example adding objects to the game while it's running, add a few each frame instead of all in one frame

  • Use System.Stopwatch to measure time in Unity so you can see if what you are optimizing is improving

  • Use System.Text.StringBuilder to combine strings instead of string concatenation finalString = string1 + string2

  • Using go.CompareTag("Enemy") is faster than go.tag == "Enemy" (Source)

  • Layers are faster than tags when it comes to working with collision logic

  • Mathf.Max(a, Mathf.Max(b, c)) is faster than Mathf.Max(a, b, c) because calling Max with three arguments means invoking Mathf.Max(params int[] args), which then allocates 36 bytes on the heap for each function call. Calling functions with a variable number of arguments actually allocates those args on the heap in a temporary array

  • There is no performance difference between for and while loops

  • Raycasts. Don't extend the ray's length more than you need to. The greater the ray, the more objects need to be tested against it. Don't use use Raycasts inside a FixedUpdate() function, sometimes even inside an Update() may be an overkill. Be specific on what the ray should hit and always try to specify a layer mask on the raycast function. If you want a ray to hit an object which is on layer which id is 10, what you should specify is 1<<10, if you want for the ray to hit everything except what is on layer 10 then simply use the bitwise complement operator (~)

  • Don't use FindObject. It's better to store the objects you want to find in a list and then you modify the list as the objects are active/inactive with OnEnable and OnDisable

  • Camera.main calls FindObjectWithTag("MainCamera") so cache it instead once in the beginning