using System; using System.Collections.Generic; using UnityEngine; namespace AlicizaX { /// /// 所有单例的统一管理器。 /// [DefaultExecutionOrder(-9999)] public sealed class SingletonManager : MonoBehaviour { private static SingletonManager _instance; private readonly Dictionary _singletons = new(); public static SingletonManager Instance { get { if (_instance == null) { // 查找是否已有实例 _instance = FindFirstObjectByType(); if (_instance == null) { var obj = new GameObject("[SingletonManagers]"); _instance = obj.AddComponent(); DontDestroyOnLoad(obj); } } return _instance; } } /// /// 注册一个单例。 /// internal void Register(T instance) where T : Component { var type = typeof(T); if (!_singletons.ContainsKey(type)) { _singletons[type] = instance; instance.transform.SetParent(transform, false); } } /// /// 注销单例。 /// internal void Unregister(T instance) where T : Component { var type = typeof(T); if (_singletons.TryGetValue(type, out var current) && current == instance) _singletons.Remove(type); } /// /// 获取一个已注册的单例(若不存在则返回 null) /// public T Get() where T : Component { _singletons.TryGetValue(typeof(T), out var result); return result as T; } } /// /// 泛型单例基类。 /// 自动注册到 SingletonManager。 /// 支持动态创建与销毁。 /// public abstract class Singleton : MonoBehaviour where T : Component { private static T _instance; private static readonly object _lock = new(); public static T Instance { get { if (_instance != null) return _instance; lock (_lock) { if (_instance != null) return _instance; // 检查 SingletonManager 是否存在 var manager = SingletonManager.Instance; // 查找场景中是否已经存在该类型 _instance = manager.Get(); if (_instance == null) { var obj = new GameObject(typeof(T).Name); _instance = obj.AddComponent(); manager.Register(_instance); } return _instance; } } } protected virtual void Awake() { if (_instance == null) { _instance = this as T; SingletonManager.Instance.Register(_instance); } else if (_instance != this) { Destroy(gameObject); return; } } protected virtual void OnDestroy() { if (_instance == this) { SingletonManager.Instance.Unregister(this as T); _instance = null; } } } }