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