单例通过基类实现

在具有多个单例类的项目中(通常就是这种情况),将单例行为抽象为基类可以简洁明了:

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 原则(不要重复自己),可读性和便利性很小。