什么是单例?
一个类有且仅有一个实例,它自行实例化并向整个系统提供这个实例。

作为最简单的设计模式之一,单例模式经常会被使用,但Unity中的写法与其他开发环境下有所不同。
要在Unity中保持一个单例,又要很方便的调用MonoBehaviour对象不报错,要对写法进行改造。
先上单例基类代码:MonoSingleton.cs

using UnityEngine;

/// <summary>
/// MonoBehaviour单例基类<br/>
/// <para>ZhangYu 2018-03-14</para>
/// <para>Blog:https://segmentfault.com/a/1190000015261387</para>
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour {

    // 单例
    private static T instance;

    /// <summary>获取单例</summary>
    public static T GetInstance() {
        if (instance == null) {
            // 在已存在的脚本中查找单例
            instance = (T)FindObjectOfType(typeof(T));

            // 创建单例
            if (instance == null) new GameObject(typeof(T).Name).AddComponent<T>();
        }
        return instance;
    }

    // 获取单例/销毁重复对象
    protected virtual void Awake() {
        if (instance == null) {
            instance = this as T;
            DontDestroyOnLoad(gameObject);
            Init();
        } else if (instance != this) {
            if (instance.gameObject != gameObject) {
                Destroy(gameObject);
            } else {
                Destroy(this);
            }
        }
    }

    // 重空单例
    protected virtual void OnDestroy() {
        if (instance == this) instance = null;
    }

    // 初始化
    protected virtual void Init() {

    }

}

用法:
自定义的单例继承Singleton并传入自己的类型。
例如:GameManager.cs

using UnityEngine;

public class GameManager : Singleton<GameManager> {

    protected override void Init() {
        // 在这里写自己的代码
    }

}

情况1:当场景中已经存在一个GameManager,其他后出现的GameManager对象都会被销毁,保证系统中有且仅有一个实例。

情况2:当场景中无GameMananger时,会创建一个叫GameMananger的物体并附加脚本,自行实例化。
测试代码:Test.cs

using UnityEngine;

public class Test : MonoBehaviour {

    private void Start () {
        print(GameManager.getInstance());
    }
    
}

运行结果
自行实例化


冰封百度
233 声望43 粉丝

Unity游戏程序员一枚。生命不息,学习不止。


下一篇 »
JSON教程