// Magica Cloth 2. // Copyright (c) 2023 MagicaSoft. // https://magicasoft.jp using UnityEngine; namespace MagicaCloth2 { /// /// 基本的なシングルトンテンプレート /// ・シーンに無い場合は作成する /// ・自動初期化呼び出し機能 /// ・DontDestroyOnLoad設定 /// ・実行前でもInstanceアクセス可能 /// /// public abstract class CreateSingleton : MonoBehaviour where T : MonoBehaviour { private static T instance; /// /// 初期化フラグ /// private static T initInstance; private static bool isDestroy; /// /// Reload Domain 対応 /// ※残念ながらジェネリッククラスでは[RuntimeInitializeOnLoadMethod]が利用できないため、 /// この初期化関数を派生元で[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] /// を使用して呼び出さなければならない /// protected static void InitMember() { instance = null; initInstance = null; isDestroy = false; } public static T Instance { get { if (instance == null) { // FindObjectOfTypeはそれなりに負荷がかかるので注意! // 非アクティブのオブジェクトは発見できないので注意! #if UNITY_2023_1_OR_NEWER instance = FindFirstObjectByType(); #else instance = FindObjectOfType(); #endif if (instance == null && Application.isPlaying) { var obj = new GameObject(typeof(T).Name); instance = obj.AddComponent(); } } // 初期化 InitInstance(); return instance; } } private static void InitInstance() { if (initInstance == null && instance != null && Application.isPlaying) { // シーン切り替えでもオブジェクトが消えないように設定 //DontDestroyOnLoad(instance.gameObject); // 初期化呼び出し var s = instance as CreateSingleton; s.InitSingleton(); initInstance = instance; } } /// /// インスタンスが存在する場合にTrueを返します /// /// public static bool IsInstance() { return instance != null && isDestroy == false; } /// /// Awake()でのインスタンス設定 /// protected virtual void Awake() { if (instance == null) { instance = this as T; InitInstance(); } else if (instance != this) { // 2つ目のコンポーネントを発見 var s = instance as CreateSingleton; s.DuplicateDetection(this as T); // 2つ目のコンポーネントは破棄する Destroy(this.gameObject); } } protected virtual void OnDestroy() { // インスタンスクラスならば無効化フラグを立てる if (instance == this) { isDestroy = true; } } /// /// 2つ目の破棄されるコンポーネントを通知 /// /// protected virtual void DuplicateDetection(T duplicate) { } /// /// 内部初期化 /// protected abstract void InitSingleton(); } }