125 lines
3.2 KiB
C#
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
|
|
}
|
|
}
|