unity3d Singleton Implementation through base class


Example

In projects that feature several singleton classes (as is often the case), it can be clean and convenient to abstract the singleton behaviour to a base class:

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

public abstract class MonoBehaviourSingleton<T> : MonoBehaviour {
    
    private static Dictionary<Type, object> _singletons
        = new Dictionary<Type, object>();

    public static T Instance {
        get {
            return (T)_singletons[typeof(T)];
        }
    }

    void OnEnable() {
        if (_singletons.ContainsKey(GetType())) {
            Destroy(this);
        } else {
            _singletons.Add(GetType(), this);
            DontDestroyOnLoad(this);
        }
    }
}

A MonoBehaviour may then implement the singleton pattern by extending MonoBehaviourSingleton. This approach allows the pattern to be utilised with a minimal footprint on the Singleton itself:

using UnityEngine;
using System.Collections;

public class SingletonImplementation : MonoBehaviourSingleton<SingletonImplementation> {

    public string Text= "String Instance";

    // Use this for initialisation
    IEnumerator Start () {
        var demonstration = "SingletonImplementation.Start()\n" +
                            "Note that the this text logs only once and\n"
                            "only one class instance is allowed to exist.";
        Debug.Log(demonstration);
        yield return new WaitForSeconds(2f);
        var secondInstance = new GameObject();
        secondInstance.AddComponent<SingletonImplementation>();
    }
   
}

Note that one of the benefits of the singleton pattern is that a reference to the instance may be accessed statically:

// Logs: String Instance
Debug.Log(SingletonImplementation.Instance.Text);

Keep in mind though, this practise should be minimised in order to reduce coupling. This approach also comes at a slight performance cost due to the use of Dictionary, but as this collection may contain only one instance of each singleton class, the trade-off in terms of the DRY principle (Don't Repeat Yourself), readability and convenience is small.