Skip to content

Instantly share code, notes, and snippets.

@elumixor
Created September 19, 2019 12:52
Show Gist options
  • Save elumixor/ba90b2b24220c38b6e0189e88ad58f3b to your computer and use it in GitHub Desktop.
Save elumixor/ba90b2b24220c38b6e0189e88ad58f3b to your computer and use it in GitHub Desktop.
Unity MonoBehaviour Singleton, that is persistent and disallowing duplicates
using UnityEditor;
using UnityEngine;
namespace Shared.SingletonBehaviour {
/// <summary>
/// Singleton is not guaranteed to be initialized at OnValidate and Awake
/// </summary>
/// <typeparam name="T"></typeparam>
[ExecuteInEditMode]
public class SingletonBehaviour<T> : MonoBehaviour where T : SingletonBehaviour<T> {
// ReSharper disable once StaticMemberInGenericType
private static readonly object Lock = new object();
private static T instance;
private static void AssignInstance() {
var instances = FindObjectsOfType<T>();
if (instances.Length > 1) {
if (instance == null) {
for (var i = 1; i < instances.Length; i++) {
Debug.LogWarning(
$"[Singleton] Instance '{typeof(T)}' already exists in the scene, removing {instances[i]}");
DestroyImmediate(instances[i].gameObject);
}
instance = instances[0];
} else {
foreach (var i in instances) {
if (i != instance) {
Debug.LogWarning(
$"[Singleton] Instance '{typeof(T)}' already exists in the scene, removing {i}");
DestroyImmediate(i.gameObject);
}
}
}
} else if (instances.Length == 1)
instance = instances[0];
else
instance = new GameObject($"{typeof(T)} (Singleton)").AddComponent<T>();
// todo: #if UNITY_EDITOR... conditional check
if (Application.isPlaying) {
DontDestroyOnLoad(instance);
DontDestroyOnLoad(instance.gameObject);
}
}
// todo: Replace existing singleton behaviour in scene
protected virtual void Awake() {
lock (Lock) AssignInstance();
}
protected static T Instance {
get {
lock (Lock) {
if (instance == null) AssignInstance();
return instance;
}
}
}
private void OnDestroy() {
lock (Lock) if (instance == this) instance = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment