WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Runtime/ResourceManager/Util/ComponentSingleton.cs
2025-01-07 02:06:59 +01:00

125 lines
3.2 KiB
C#

using UnityEditor;
namespace UnityEngine.ResourceManagement.Util
{
/// <summary>
/// Creates a singleton.
/// </summary>
/// <typeparam name="T">The singleton type.</typeparam>
[ExecuteInEditMode]
public abstract class ComponentSingleton<T> : MonoBehaviour where T : ComponentSingleton<T>
{
static T s_Instance;
/// <summary>
/// Indicates whether or not there is an existing instance of the singleton.
/// </summary>
public static bool Exists => s_Instance != null;
/// <summary>
/// Stores the instance of the singleton.
/// </summary>
public static T Instance
{
get
{
if (s_Instance == null)
{
s_Instance = FindInstance() ?? CreateNewSingleton();
}
return s_Instance;
}
}
static T FindInstance()
{
#if UNITY_EDITOR
foreach (T cb in Resources.FindObjectsOfTypeAll(typeof(T)))
{
var go = cb.gameObject;
if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave))
return cb;
}
return null;
#else
return FindObjectOfType<T>();
#endif
}
/// <summary>
/// Retrieves the name of the object.
/// </summary>
/// <returns>Returns the name of the object.</returns>
protected virtual string GetGameObjectName() => typeof(T).Name;
static T CreateNewSingleton()
{
var go = new GameObject();
if (Application.isPlaying)
{
DontDestroyOnLoad(go);
go.hideFlags = HideFlags.DontSave;
}
else
{
go.hideFlags = HideFlags.HideAndDontSave;
}
var instance = go.AddComponent<T>();
go.name = instance.GetGameObjectName();
return instance;
}
private void Awake()
{
if (s_Instance != null && s_Instance != this)
{
DestroyImmediate(gameObject);
return;
}
s_Instance = this as T;
}
/// <summary>
/// Destroys the singleton.
/// </summary>
public static void DestroySingleton()
{
if (Exists)
{
DestroyImmediate(Instance.gameObject);
s_Instance = null;
}
}
#if UNITY_EDITOR
void OnEnable()
{
EditorApplication.playModeStateChanged += PlayModeChanged;
}
void OnDisable()
{
EditorApplication.playModeStateChanged -= PlayModeChanged;
}
void PlayModeChanged(PlayModeStateChange state)
{
if (state == PlayModeStateChange.ExitingPlayMode)
{
if (Exists)
{
DestroyImmediate(Instance.gameObject);
s_Instance = null;
}
}
}
#endif
}
}