Skip to content

Instantly share code, notes, and snippets.

@MisterKidX
Last active November 3, 2025 15:14
Show Gist options
  • Select an option

  • Save MisterKidX/2093305acc70edbd2efca971777eb84c to your computer and use it in GitHub Desktop.

Select an option

Save MisterKidX/2093305acc70edbd2efca971777eb84c to your computer and use it in GitHub Desktop.
added documentation and logs
using UnityEngine;
/// <summary>
/// provides an easy way to create singletons in unity based on monobehaviours
/// </summary>
/// <typeparam name="T">T must be the same type as the declaring type</typeparam>
public class MBSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
protected static T _instance;
public static T Instance
{
get
{
if (_instance == null)
GetInstance();
return _instance;
}
}
/// <summary>
/// override this in your derived class to decide if the object will be kept between scenes. Default is set to true.
/// </summary>
protected virtual bool AddToDontDestroyOnLoad => true;
private static void GetInstance()
{
// check if other objects exist
var singletons = FindObjectsByType<T>(FindObjectsInactive.Include, FindObjectsSortMode.None);
if (singletons != null && singletons.Length > 0)
{
if (singletons.Length > 1)
Debug.LogWarning("You should not have more than one singleton monobehaviour present at the same scene. Which singleton is preserved is not guaranteed.", singletons[0]);
return;
}
// otherwise create new singleton
var go = new GameObject(typeof(T).Name + "_singleton");
go.AddComponent<T>();
go.tag = "Singleton";
}
/// <summary>
/// override this function to add custom logic to the construction of the singleton at **runtime**.
/// </summary>
/// <remarks>
/// Construct is not automatically called if the object already exists in the opened scene
/// </remarks>
protected virtual void Construct() { }
/// <summary>
/// Handles the assignment and construction of the selected singleton. Instead of overriding Awake(), override Construct() instead
/// </summary>
protected virtual void Awake()
{
if (_instance == null)
{
_instance = this as T;
if (AddToDontDestroyOnLoad)
DontDestroyOnLoad(gameObject);
Construct();
}
else if (_instance != null && _instance != this)
Destroy(this);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment