Mobile devices are becoming more and more powerful. However, not all your users will have high-end mobile devices, so you should keep a low-powered device handy for testing the performance of your games.
Here are 10 ways not usually mentioned on how to improve mobile Unity performance. The usual advice (use low-poly models, minimal lights, few effect, etc) is good. But if you still need need to increase performance, try these tricks:
Unity 5 introduced the Standard Shader, relegating a bunch of shaders to the Legacy Shaders category. The Standard Shader accomplishes most of the things you’ll need. However, on older mobile devices, performance may suffer. Low-poly models that you download from the Asset Store may already be using one of the lightweight Mobile Shaders, instead. But check that ALL your assets are using a mobile shader if performance is still a problem. I recommend seeing if you can achieve acceptable results with the Mobile/VertexLit (only directional lights) shader. You’ll notice an immediate performance boost.
For transparency effects that you have used a standard shader for, consider switching to one of the Mobile/Particles shaders. You can achieve decal, smoke and cloud effects with these very fast shaders at a fraction of the performance cost of standard shaders. If you still can’t achieve the transparency effect you need, see if one of these Unlit Mobile shaders will help.
If possible, disable cast shadows, receive shadows, light probe use and reflection probes for your meshes. If you need dynamic-looking shadows (but are using Unity free or suffering with low performance on mobile), consider using this Fast Shadow Projector package.
Oftentimes, assets from the Asset Store come with high-res textures. You can override the exported texture size per platform in the inspector. Try to reuse textures where possible and export them as small as possible. This will improve both framerate AND reduce memory usage.
Also, consider doing any flat-shading with a piece of a colour-swatch texture. Many mobile-ready assets from the store use this technique, or a similar vertex-colouring trick. You can reuse the colour-swatch texture to shade other assets in flat colours. Doing so will boost performance, because you have 1 texture to upload to the GPU and all these meshes should be batched into a single draw call. For example: for flat shading, choose your colour-swatch texture, set the tiling to 0,0 and adjust the texture offsets to get the colour you want – rinse and repeat.
This is rather obvious one. But you can often replace lighting and post effects with a single, overlaid image in a canvas, to achieve some nice effects with only a single draw call (e.g. dirt, vignette, etc).
Never use GetComponent, FindWithTag (or any other methods with find in their name) in your Update, FixedUpdate, or LateUpdate methods. These are wasteful calls that will be called multiple times per frame. You should store a reference to any components or GameObjects you need in your Awake or Start methods and use those references in your updates.
6) Disable static Game Objects
If you’ve attached a script to a game object (especially an often used prefab), in order to do some initial setup and perhaps some collision triggers, but you don’t require calls to Update, FixedUpdate and LateUpdate, you should disable this MonoBehaviour like so:
enabled = false;
7) Mark static objects
For any objects in your scene which are not going to move (but may still require calls to MonoBehaviour methods), mark the object as ‘static’ in its Unity Editor properties. This will reduce the runtime resources used to render and update these objects.
8) Draw call batching
Unity will do its best to render groups of similar objects in ‘batches’ as a single draw operation, but there are a few caveats to this. You should make yourself familiar with the requirements for successful draw call batching – especially if you have many objects in your scene and are experiencing significant slow-down.
9) Project Settings
There are mentions elsewhere about fiddling with Physics and Time settings (in your Project Settings), in order to achieve smoother and more consistent performance across devices. However, there is a hidden gem in Edit > Project Settings > Player. Namely, the Optimize Mesh Data option. If none of your Shaders use Normal Mapping (unlikely if you’re targeting mobile), enable this to improve performance AND reduce the file size of your game!
10) Camera Clipping Planes
You may also to be able to squeeze a little more performance out of your game by adjusting the Camera’s Clipping Planes. Also, the closer the values of near and far clipping plane, the more precision is afforded the GPU for z-sorting calculations, resulting in a reduction in z-fighting (flickering textures), which may be worse on certain, older GPUs.
Bonus tip – DOTS?
If you’ve got particularly ambitious plans for your game or simulation, you may need to refactor your game to use Unity’s brand new Data Oriented Technology Stack, DOTS for short. Here’s a great video introducing DOTS and the Entity Component System:
If you find any cool, undocumented ways to increase mobile performance, feel free to leave a comment below. Happy optimizing!