// 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();
}
}