MonoSingleton
Coding Style wiki
MonoSingleton<T> is the MonoBehaviour singleton base class of SingletonSystem (thread-lock protected). When accessing the instance, it first looks for an existing instance in the scene, otherwise automatically creates a GameObject with the component attached; it supports DontDestroyOnLoad cross-scene persistence control and replaces Unity's Awake / Start / OnDestroy with the OnCreate / OnStart / OnRelease lifecycle hooks.
| Namespace | OxGKit.SingletonSystem |
| Type | public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> |
| Source | MonoSingleton.cs |
using OxGKit.SingletonSystem;
Reminder For pure data or logic manager classes that do not need to live on a GameObject, use NewSingleton instead.
Quick Start
using OxGKit.SingletonSystem;
public class GameManager : MonoSingleton<GameManager>
{
protected override void OnCreate() { /* Call by Unity.Awake */ }
protected override void OnStart() { /* Call by Unity.Start */ }
protected override void OnRelease() { /* Call by Unity.OnDestroy */ }
public void SaveGame() { /* ... */ }
}
// Get and access the instance (find-or-create, DontDestroyOnLoad by default)
GameManager.GetInstance().SaveGame();
// Scene-scoped singleton (destroyed with the scene)
GameManager.GetInstance(dontDestroyOnLoad: false);
// Explicit initialization at boot (warm-up)
GameManager.InitInstance();
// Destroy the instance (GameObject included)
GameManager.DestroyInstance();
General Rules
Lifecycle Mapping
The base class implements Awake(), Start(), and OnDestroy() as private methods and invokes the following hooks guarded by flags:
| Unity Method | Hook | Flag |
|---|---|---|
Awake | OnCreate | isCreated |
Start | OnStart | isStarted |
OnDestroy | OnRelease | isReleased (also resets isCreated, isStarted, and the instance reference) |
Important Do not implement Awake(), Start(), or OnDestroy() (occupied by the base class); every other Unity method (Update, OnEnable, etc.) can be implemented normally.
Instance Creation Rules
- Scene-placed instance: registers itself as the singleton in
Awake, and the dontDestroyOnLoad field on the Inspector decides whether it persists (see Module Intro). - Created from code: when GetInstance is called and no instance exists, it looks for an existing scene instance (
FindObjectsOfType, first found wins), otherwise automatically creates anew GameObject(typeof(T).Name)with the component attached.
Attention GetInstance only performs instance creation in Play Mode (Application.isPlaying).
Attention Multiple scene-placed instances of the same type are not automatically deduplicated (the first found wins); avoid placing duplicates across additively-loaded scenes.
Reminder Events registered in OnCreate / OnStart must be unregistered in OnRelease — persistent singletons accumulate stale delegates otherwise. When accessing the singleton from shutdown/teardown paths, check with CheckInstanceExists first to avoid re-creating the instance mid-quit.
Members
| Member | Description |
|---|---|
public bool dontDestroyOnLoad | (Instance field) Whether to mark the instance with DontDestroyOnLoad in Awake, default true; configurable on the Inspector for scene-placed instances. |
public static bool isCreated | Whether OnCreate has been invoked. |
public static bool isStarted | Whether OnStart has been invoked. |
public static bool isReleased | Whether the instance has been destroyed (OnRelease invoked); reset to false when a new instance runs Awake. |
Instance Management
Methods Overview
| Method | Description |
|---|---|
| GetInstance | Gets the singleton instance (find-or-create). |
| InitInstance | Initializes the singleton instance (same as calling GetInstance). |
| CheckInstanceExists | Checks if an instance exists. |
| DestroyInstance | Destroys the singleton instance. |
GetInstance
public static T GetInstance(bool dontDestroyOnLoad = true)
Gets the singleton instance (thread-lock protected). If no instance exists yet (Play Mode only), it first looks for an existing instance in the scene, otherwise automatically creates a new GameObject(typeof(T).Name) with the component attached; when the dontDestroyOnLoad parameter is true, the instance is marked and DontDestroyOnLoad is applied.
// Cross-scene persistence needed (default)
GameManager.GetInstance();
// No cross-scene persistence needed (set once at the first access)
StageManager.GetInstance(dontDestroyOnLoad: false);
Attention The dontDestroyOnLoad parameter takes effect on the first instance creation — decide it at the first access call site and keep it consistent.
InitInstance
public static void InitInstance(bool dontDestroyOnLoad = true)
Initializes the singleton instance (same as calling GetInstance); suitable for explicitly controlling the creation order during boot (warm-up), avoiding ordering issues caused by lazy creation.
private void Awake()
{
GameManager.InitInstance();
AudioManager.InitInstance();
}
CheckInstanceExists
public static bool CheckInstanceExists()
Checks if an instance exists (does not trigger creation).
if (GameManager.CheckInstanceExists())
GameManager.GetInstance().SaveGame();
DestroyInstance
public static void DestroyInstance(bool gameObjectIncluded = true)
Destroys the singleton instance; when gameObjectIncluded is true, the GameObject is destroyed as well, when false, only the component itself is destroyed. Destruction triggers OnRelease and resets the state flags and the instance reference, after which a new instance can be created again.
// Destroy the GameObject as well (default)
GameManager.DestroyInstance();
// Destroy the component only (keep the GameObject)
GameManager.DestroyInstance(gameObjectIncluded: false);
Lifecycle Hooks
Methods Overview
| Method | Description |
|---|---|
| OnCreate | Invoked by Unity Awake. |
| OnStart | Invoked by Unity Start. |
| OnRelease | Invoked by Unity OnDestroy. |
OnCreate
protected abstract void OnCreate()
Invoked by Unity Awake (guarded by the isCreated flag to fire only once); implement initialization logic here.
OnStart
protected abstract void OnStart()
Invoked by Unity Start (guarded by the isStarted flag to fire only once); implement startup logic here.
OnRelease
protected abstract void OnRelease()
Invoked by Unity OnDestroy; implement release logic here (unregister events, release resources). Afterwards isReleased becomes true, and isCreated, isStarted, and the instance reference are reset.