What is the Singleton? 

The singleton pattern can be a rather technical software engineering topic to tackle and certainty not one I'm going to exhaust in a single blog post. But don’t let the technical nature of the singleton class structure put you off.

Whilst it may seem daunting to those just getting started with programming, it is something that I strongly recommend learning sooner rather than later. Otherwise you may just end up developing some bad coding habits as you hack your way around the need for a singleton. 

In essence a singleton pattern allows for an object to be referenced globally by your game. This can only ever be done if there is but a single instance.  Game development, particularly in Unity lends itself quite well for singletons to be useful. You often just have single instances of objects (e.g. player, game controller or score) but want to be able to access them from most game objects in the scene.   

Com'on Just Show Me the Code Already! 

Alright Fine! The simplest of singletons require just two lines of code. One to create a static reference to the class itself and another to create an instance.

 

 
public class ExampleSingleton : MonoBehaviour
{
    public static ExampleSingleton instance;
    public float myFloat;
    // Start is called before the first frame update
    void Awake()
    {
        instance = this;
    }
}

You can then reference the instance of a class and all of it’s associated properties and methods.

 

  public class ExampleSingleton : MonoBehaviour
{
public class UsingSingleton : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        ExampleSingleton.instance.myFloat = 10f;
    }
}
}

Boom that’s it. You’ve written your first singleton script and are ready to go. But before you go, just make sure you only ever have one in the scene or you're going to get a game crashing error! Perhaps before you create your instance you could check to see if it exists already? If it does exist you can delete the object you just created. If you did that your code might look like this;

  
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExampleSingleton : MonoBehaviour
{
    public static ExampleSingleton instance; 
    // Awake is called before the first frame update
    void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(this.gameObject);
        }      
    }
}

This is where most people stop. And why not? it seems pretty good doesn't it? It certainly achieves the initial purpose. The biggest flaw with this code is that if you ever try to make a reference to it within the awake method of another class you might just get a null exception. If you try to implement this coding pattern outside the context of Unity you could very well get multiple threads trying to access the instance simultaneously. To put bluntly; the above code will work in many situations, but can fail just as often. So what is the fix? We need to ensure that the instance of the singleton exists, regardless of when we attempt to access it. For this want to create get method that other classes will use and importantly within that get method check that our singleton even exists in the scene.

  
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExampleSingleton : MonoBehaviour
{
    private static ExampleSingleton instance;
    public static ExampleSingleton MyProperty
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType(); //will return null if no such object exsists
                if (instance == null)
                {
                    GameObject obj = new GameObject();
                    instance = obj.AddComponent();
                }
            }
            return instance;
        }
    }

    // Awake is called before the first frame update
    void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(this.gameObject);
        }       
    }
}

This is the code I’ve always used my games, that was until now at least. When researching for this blog I discovered that even this code, whilst safe to run in 99.9% of cases, is not quite complete. The ultimate step is to create a generic singleton statement that other classes can simply inherit from. Alas, no more copying the same code for each class that you want to make a singleton. Rather than just copy the the code here however, I will direct you the UnityGeek blog on the topic that outlines how to achieve this.

Is There Another Way?

When I first learnt about Singletons I may of gone somewhat overboard and quickly began making every class I created a singleton. What followed were games that I couldn’t scale or keep track off. I lost track of what I was using as a Singleton and which objects were been referenced and when. My code felt sloppy and my memory management was suffering in the process. I've since learned to keep Singletons a rare sighting in my games, reserving them for the most important of jobs. Like a level controller, or perhaps class that was managing data for the whole scene. Instead I learnt that I was able to exchange most of my Singleton statements for Unity Events and Scriptable Objects… both topics to be covered in a future blog.

References and Other Resources

  1. Kristiel, 2014, How to Create a Singleton in Unity 3D“ Unity Geek, 2016
  2. Unity Geek, 2016 , Singleton : Implementation in Unity 3d C#
  3. Alex Theedom, 2016, Singleton Pattern: The Good, the Bad, and the Ugly
  4. Ted Neward, 2016, The Singleton Pattern, 20 Years Later
  5. Unity3D , Tutorial : Writing the Game Manager