單例通過基類實現

在具有多個單例類的專案中(通常就是這種情況),將單例行為抽象為基類可以簡潔明瞭:

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);
        }
    }
}

然後,MonoBehaviour 可以通過擴充套件 MonoBehaviourSingleton 來實現單例模式。這種方法允許在 Singleton 本身上以最小的佔用空間使用模式:

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>();
    }
   
}

請注意,單例模式的一個好處是可以靜態訪問對例項的引用:

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

但請記住,應儘量減少這種做法,以減少耦合。由於使用了 Dictionary,這種方法也會帶來輕微的效能成本,但由於這個集合可能只包含每個單例類的一個例項,因此在 DRY 原則(不要重複自己),可讀性和便利性很小。