1.MonoSingleton
代码部分
using UnityEngine;/// <summary>
/// MonoBehaviour单例基类
/// 需要挂载到GameObject上使用
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{private static T _instance;private static readonly object _lock = new object();private static bool _applicationIsQuitting = false;public static T Instance{get{if (_applicationIsQuitting){Debug.LogWarning($"[MonoSingleton] Instance '{typeof(T)}' already destroyed on application quit. Won't create again.");return null;}lock (_lock){if (_instance == null){_instance = FindObjectOfType<T>();if (_instance == null){GameObject singletonObject = new GameObject();_instance = singletonObject.AddComponent<T>();singletonObject.name = typeof(T).ToString() + " (Singleton)";// 可选:让单例对象在场景切换时不被销毁//DontDestroyOnLoad(singletonObject);}}return _instance;}}}protected virtual void Awake(){if (_instance == null){_instance = this as T;DontDestroyOnLoad(gameObject);}else if (_instance != this){Debug.LogWarning($"Another instance of {typeof(T)} already exists. Destroying this one.");Destroy(gameObject);}}protected virtual void OnApplicationQuit(){_applicationIsQuitting = true;}protected virtual void OnDestroy(){if (_instance == this){_instance = null;}}
}
说明
继承MonoSingleton的物体需要能挂载到场景物体上,即继承MonoBehaviour
我在MonoSingleton中将DontDestroyOnLoad(singletonObject)取消掉了,如果需要跨场景的话需要在继承的脚本中重写Awake方法
protected override void Awake()
{base.Awake();DontDestroyOnLoad(gameObject);
}
2.Singleton
代码部分
/// <summary>
/// 纯C#单例基类
/// 不需要挂载到GameObject上,可以直接调用
/// </summary>
public class Singleton<T> where T : class, new()
{private static T _instance;private static readonly object _lock = new object();public static T Instance{get{if (_instance == null){lock (_lock){if (_instance == null){_instance = new T();}}}return _instance;}}protected Singleton() { }
}
总结
本文的MonoSingleton与Singleton说明
MonoSingleton<T> 特点:
- 需要挂载到GameObject上,继承MonoBehaviour
- 线程安全的懒加载模式
- 需要手动选择处理场景切换时的持久化(DontDestroyOnLoad)
- 防止重复实例创建
- 应用退出时的安全处理
Singleton<T> 特点:
- 纯C#类,不需要挂载到GameObject
- 线程安全的懒加载模式
- 可以直接调用,无需场景依赖
- 适合数据管理、配置管理等不需要MonoBehaviour生命周期的功能
都是很经典的框架,不多做说明