Skip to content

Instantly share code, notes, and snippets.

@ncruces
Created October 27, 2022 14:26
Show Gist options
  • Save ncruces/74e0447adadd3bf94656f631d08bc20d to your computer and use it in GitHub Desktop.
Save ncruces/74e0447adadd3bf94656f631d08bc20d to your computer and use it in GitHub Desktop.
A singleton Unity3D MonoBehaviour
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