在游戏开发中多个地方需要访问同一个管理器实例的情况,如果每次都用FindObjectOfType或者拖拽到Inspector,会比较麻烦,而单例模式简化了这一点。

Unity中通常有两种方式:一种是传统的C#单例,另一种是继承MonoBehaviour的方式

基本概念

单例模式,我的理解就是全局所共有的,在任何地方都可以使用它。

单例模式有三个特点:

  • 全局唯一

  • 随时都能够访问它

  • 可以防止创建多个副本

它的主要的应用场景:游戏状态管理、音频控制、库存管理等

为什么是抽象的?

答:因为不想要被new

using UnityEngine;

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>{
	
	private static T m_Instance = null;
    
    // 在设计阶段 写脚本 没有挂载物体上 希望脚本 单例模式
	public static T instance{
        get{
			if( m_Instance == null ){
                // 从场景中查找
            	m_Instance = GameObject.FindObjectOfType(typeof(T)) as T;
                if( m_Instance == null ){
                    // 1. 直接创建一个游戏对象
                    // 2. 为这个游戏对象添加脚本组件
                    m_Instance = new GameObject("Singleton of " + typeof(T).ToString(), typeof(T)).GetComponent<T>();
                    // 初始化
					 m_Instance.Init();
                }
               
            }
            return m_Instance;
        }
    }

    // 设计阶段,写脚本,挂在物体上
    // 项目运行时【系统会帮助我们将脚本类实例化为对象(new 脚本)】
    // 项目运行时 在Awake时,在场景中找到唯一实例,记录在m_Instance中
    private void Awake(){
   
        if( m_Instance == null ){
            m_Instance = this as T;
        }
    }
 
    // 提供初始化的一种选择,可以使用Init、Start都可以
    public virtual void Init(){}
 
    // 当程序退出做清理工作! 单例模式 = null
    private void OnApplicationQuit(){
        m_Instance = null;
    }
}