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生命周期的功能
都是很經典的框架,不多做說明