BITFALL/Assets/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs

135 lines
4.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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