Created
October 27, 2022 14:26
-
-
Save ncruces/74e0447adadd3bf94656f631d08bc20d to your computer and use it in GitHub Desktop.
A singleton Unity3D MonoBehaviour
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
/// <summary> | |
/// Base class for <see cref="MonoBehaviour"/> of which there should be a single instance. | |
/// </summary> | |
/// <threadsafety>This class is <b>not</b> thread safe.</threadsafety> | |
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> | |
{ | |
static volatile T instance; | |
static GameObject owner; | |
static bool quitting; | |
/// <summary> | |
/// Gets the single instance of this class. | |
/// </summary> | |
/// <remarks> | |
/// Initializes the singleton, if necessary. | |
/// </remarks> | |
public static T Instance | |
{ | |
get | |
{ | |
Initialize(); | |
return instance; | |
} | |
} | |
/// <summary> | |
/// Initializes the singleton, creating an instance of it, if necessary. | |
/// </summary> | |
public static void Initialize() | |
{ | |
if (instance == null && !quitting) | |
{ | |
instance = FindObjectOfType<T>(); | |
if (instance == null) | |
{ | |
owner = new GameObject { hideFlags = HideFlags.HideInHierarchy }; | |
instance = owner.AddComponent<T>(); | |
DontDestroyOnLoad(owner); | |
} | |
} | |
} | |
private void Awake() | |
{ | |
if (instance == null) instance = this as T; | |
if (instance != this) Debug.LogError("Multiple instances of singleton: " + typeof(T).Name); | |
} | |
/// <summary> | |
/// Called when the <see cref="MonoBehaviour"/> will be destroyed. | |
/// </summary> | |
/// <remarks> | |
/// This method should not be overriden by derived classes, | |
/// they should implement <see cref="IDisposable"/> instead. | |
/// </remarks> | |
protected void OnDestroy() | |
{ | |
var disposable = this as IDisposable; | |
if (disposable != null) disposable.Dispose(); | |
if (instance == this) instance = null; | |
if (gameObject == owner) Destroy(owner); | |
} | |
/// <summary> | |
/// Sent to all game objects before the application is quit. | |
/// </summary> | |
/// <remarks> | |
/// This method should not be overriden by derived classes. | |
/// </remarks> | |
protected void OnApplicationQuit() | |
{ | |
quitting = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment