11
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
// 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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user