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.
If you follow the usual advice for mobile devices (use low-poly models, minimal lights, few effects and static objects where possible) you’ll be OK on most devices, but you may be caught out on some devices – resulting in annoyed users. Here are a few tricks to try if you still need to improve the performance of your Unity game.
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.
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;
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!
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.
If you find any cool, undocumented ways to increase mobile performance, feel free to leave a comment below. Happy optimising!