Arrival in Hell Dev Blog #9 – Optimisation

Apologies for the delay between that last post and this one, but development progress on the game is a little slower now since we’re focusing on some graphical side of things, so I haven’t had much to write about!

I did promise a write up regarding what I have done to optimise performance as best I can, and a few things which tripped me up for a while, so I’ll briefly go over that.

One thing I mentioned back in this post was that I made use of co-routines when performing heavy operations before saving thumbnail data to make sure the game didn’t freeze.

These thumbnails used to be recorded, scaled and saved to disk in one frame

These thumbnails used to be recorded, scaled and saved to disk in one frame

Polygon count was something that got out of hand very quickly. Alex is used to designing pre-rendered graphics mostly, and so has never really needed to keep an eye on poly count. Since we’re both running some pretty decent hardware, we never noticed a slow down. Then we tried the game on a mid-range laptop and it was lag-city. We reduced poly count as best we could to get the game back to a reasonable framerate. To view the total number of tris being rendered during play, open the stats panel in the game window.

Still quite a few tris, but seems to work smoothly on semi-decent hardware

Still quite a few tris, but seems to work smoothly on semi-decent hardware

Additionally, you can check the tri count for individual models by selecting them in the asset window.

Tri count in a mesh

Tri count in a mesh

Another problem we faced, which is hugely important, is the number of cameras we were using. We required a main game camera, another camera for the talking heads, a third to put our image effects on, and a final camera to add our scaling and letterboxing for non-native resolution displays.

The talking head camera and letterboxing camera were required since they needed different settings to a normal camera. Also, we simply culled the layers with all of the 3D geometry in since these cameras don’t actually need to render the main scene.

We found though that since the image effect camera did need to render all the scene geometry, we were essentially rendering the entire scene twice for no reason. In the end we found a way to combine the main camera and image effect camera, reducing our cameras back to the essential three.

The point I’d like to stress is that you should really try and keep the number of cameras to a minimum, and any cameras you do have should only be rendering what they need to via use of culling masks.

The profiler can be used to find how many camera render passes are happening and where there are coming from

The profiler can be used to find how many camera render passes are happening and where there are coming from

Remember to cull anything that doesn't need to be rendered by a camera

Remember to cull anything that doesn’t need to be rendered by a camera

The same thing goes for light, and is probably even more important. The number of passes will increase just as much for every (enabled) light you have in the scene. We had to be very careful how many lights we had on any any given time, we try to stick to just two or three since we only need to light one room at a time.

Using the profiler you can see which lights are being rendered and how ‘expensive’ they are

Using the profiler you can see which lights are being rendered and how ‘expensive’ they are

If the user’s machine is still not up to the task of running the game, we wanted to give the final option of lowering the quality. This means lowering the texture resolutions, removing some effects, turning off shadows etc. Luckily Unity has an amazing quality manager already so you can set your own presets and what they will do to degrade the graphics.

Unity’s built in quality settings manager

Unity’s built in quality settings manager

It’s so great that this comes built in with Unity, and all we had to do was select our options then add a simple slider to the game’s UI.

Selecting Unity quality profiles

Selecting Unity quality profiles

In case you’re interested in implementing a similar slider in your game, here is the code for ours (it even saves your last selection in PlayerPrefs)

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class QualitySlider : MonoBehaviour {

    int[] qualityLevels = new int[5] { 0, 1, 2, 3, 4 };
    string[] qualityLabels = new string[5] { "Last resort", "Basic", "Standard", "High", "Ultra" };
    int currentLevel;

    public Text labelText;
    
    void Start()
    {
        if (PlayerPrefs.HasKey("qualityLevel"))
        {
            GetComponent<Slider>().value = PlayerPrefs.GetInt("qualityLevel");
        }

        Application.targetFrameRate = 60;
    }

	void Update () {
        if (currentLevel != (int)GetComponent<Slider>().value)
        {
            currentLevel = (int)GetComponent<Slider>().value;

            QualitySettings.SetQualityLevel(qualityLevels[currentLevel], true);

            PlayerPrefs.SetInt("qualityLevel", currentLevel);
            PlayerPrefs.Save();

            labelText.text = qualityLabels[currentLevel];
        }
	}
}
The setup of our slider GameObject

The setup of our slider GameObject

That more or less covers some of the crucial steps we’ve gone through to ensure the game will run on most reasonable machines. Thanks for reading.

Share This:

2 thoughts on “Arrival in Hell Dev Blog #9 – Optimisation

  1. Pingback: Cıvata

  2. Pingback: Astropay

Leave a Reply

Your email address will not be published. Required fields are marked *

*