UNITY 5.6: Optimising your scene with frame debugger.

While running the game on Gear VR I noticed a slight lag at certain places of the scene and being an idealist I decided to optimise it to make sure users don’t ever get discomfort from playing it. After spending a bit of time playing around with different approaches here is what I’ve done and what really helped. Looking at the stats inside of the editor I found that the number of Batches if rather high for a game that will be played on mobile devices. Sometimes it would go over a hundred and it felt like those places where the number of batches were high were also the places where I experienced the lag when testing on actual device.

Note the number of “Batches” and “Saved by batching”

Approach #1: Per Layer Culling

As the Documentation says:

Normally Camera skips rendering of objects that are further away than farClipPlane. You can set up some Layers to use smaller culling distances using layerCullDistances

What this means is that you can specify layers which your camera will skip rendering despite them being closer than the Plane Distance setting of your camera. This is very useful for hiding smaller details of the scene and only render them when you really need to. E.g. when player comes close to them. I decided to put the floor and perimeter objects in a layer that will be always drawn and put smaller objects into a layer that will be only rendered at distance of 350 units. Here is an example of the script that I used.

This resulted in an interesting effect that I have seen many times in different games, for example in GTA, if you fly over the city on a chopper or a plane you will see how objects in the distance at first look like just blocks or cubes and only when you get closer to them they will get more detailed. This is a slightly more advanced approach from the one that I was after but I think the main idea was the same. As opposed to hiding the objects you can have two versions of them, one that’s just a block and the other one that’s detailed and using the per layer culling you can show the block one from far and display the detailed version when player get’s closer.

This improved the situation a bit but the game was still laggy at times.

Approach #2: Frame Debugger

After researching some more I found that Unity 5.6 has a pretty cool new feature called Frame Debugger it was described in this blog post by Valentin Simonov. It allows you to see exactly why some Draw calls cannot be Batched together. In my case most of the time the reason was that the meshes were lightmapped and their lightmaps were in different files. That made sense because I used really small lightmaps to save space for Cardboard builds. After I increased the lightmap size, the number of “Batches” had reduced and the number “Saved by batching” had increased in the Stats panel.

Note the number of “Batches” and “Saved by batching”

One other feature that found during this optimisation was VR project Linting that comes with Oculus OVR plugin. You can access it via Tools > Oculus > Audit Project for VR Performance Issues. This will launch a linter which will list things that might cause any potential performance issues with your project. My understanding is that it is optimised for VR projects specifically.

Thanks for reading!