一:目的

当设计一个Manager时候,我们希望整个程序只有一个该Manager的对象实例,最先想到的实现方法是这样的

public class XXXManager
{
    private static XXXManager _instance = null;
    public static XXXManager Ins
    {
        get
        {
            if (_instance == null)
            {
                _instance = new XXXManager();
            }
            return _instance;
        }
    }
}

如果每一个管理器类都实现一遍以上的单例代码会造成代码的重复,所以我们要想办法把重复的代码抽离出来 

二:解决的问题及优点


——解决了实现单例代码的重复问题

——动态创建空物体并挂载脚本,不需要手动创建物体和挂载脚本


三:使用方法

需要实现单例的类直接继承单例模版即可,有继承MonoBehaviour和不继承MonoBehaviour两种

public class GameMgr : MonoSingleton<GameMgr>
{
 
}
 
public class UIMgr : Singleton<UIMgr>
{
 
}

四:代码实现

/// <summary>
/// 不继承Mono的单例模版
/// </summary>
public abstract class Singleton<T>
    where T : new()
{
    private static T _instance;
    public static T Ins
    {
        get
        {
            if (_instance == null)
            {
                _instance = new T();
                (_instance as Singleton<T>).Init();
            }
            return _instance;
        }
    }
 
    /// <summary>
    /// 子类初始化的一些操作
    /// </summary>
    protected virtual void Init()
    {
 
    }
}
using UnityEngine;
 
/// <summary>
/// 继承Mono的单例模版
/// </summary>
public abstract class MonoSingleton<T> : MonoBehaviour
    where T : MonoSingleton<T>
{
    private static T _instance;
    public static T Ins
    {
        get
        {
            if (_instance == null)
            {
                GameObject go = null;
                T t = FindObjectOfType<T>();
                if (t == null)
                {
                    go = new GameObject(typeof(T).Name);
                    _instance = go.AddComponent<T>();
                }
                else
                {
                    go = t.gameObject;
                    go.name = typeof(T).Name;
                    _instance = go.GetComponent<T>();
                }
 
                DontDestroyOnLoad(go);
            }
            return _instance;
        }
    }
}

图片来源:页游