using UnityEngine; internal interface I_Singleton { } public abstract class Singleton_Mono : MonoBehaviour, I_Singleton where T : Singleton_Mono { private static T singleton; private static object _lock = new object(); public static T Singleton { get { if (singleton == null) { lock (_lock) { T obj = SceneObjectLookupCache.FindFirst(); if (obj != null) { obj.TryGetComponent(out Singleton_Mono s); } if (obj == null) { var gameObj = new GameObject(typeof(T).Name); obj = gameObj.AddComponent(); if (!obj.Is_Singleton_Auto()) { Destroy(obj.gameObject); return null; } } singleton = obj; } } return singleton; } } private void Awake() { var s = Singleton; if (s != null && singleton != this) Destroy(gameObject); if (s != this) return; Init(); } public T Init() { if (singleton == this) { In_Init(); } return singleton; } protected abstract bool Is_Singleton_Auto(); protected abstract void In_Init(); protected virtual void OnDestroy() { if (singleton == this) { singleton = null; } } } public class Singleton_Static where T : new() { protected static T singleton; private static object _lock = new object(); public static T Singleton { get { if (singleton == null) { lock (_lock) { singleton ??= new T(); } } return singleton; } } }