using System; using System.Collections.Generic; using System.Reflection; using UnityEngine; using UnityEngine.SceneManagement; public class MonoBehaviourSingleton : MonoBehaviourExtended where T : MonoBehaviour { private static readonly Dictionary instances = new Dictionary(); public static T Instance { get { Type typeFromHandle = typeof(T); if (!instances.TryGetValue(typeFromHandle, out var value)) { bool flag = false; MethodInfo methodInfo = typeFromHandle.GetMethod("GetComponentInChildren", new Type[0]).MakeGenericMethod(typeFromHandle); for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); GameObject[] rootGameObjects = sceneAt.GetRootGameObjects(); foreach (GameObject gameObject in rootGameObjects) { Transform obj = gameObject.transform; object[] parameters = new Type[0]; object obj2 = methodInfo.Invoke(obj, parameters); if (obj2 != null) { return obj2 as T; } } if (!sceneAt.isLoaded) { flag = true; } } if (flag) { return null; } MonoBehaviourExtended.LogWarning("Not found " + typeFromHandle.Name + " in the scene!"); MonoBehaviourExtended.Log("Creating new instance of " + typeFromHandle.Name + ". Start() will be delayed one frame!"); GameObject obj3 = new GameObject(typeFromHandle.Name, typeFromHandle); UnityEngine.Object.DontDestroyOnLoad(obj3); return obj3.GetComponent(); } return value as T; } private set { instances.Add(typeof(T), value); } } protected new void Awake() { if (!instances.ContainsKey(typeof(T))) { Instance = this as T; } else { MonoBehaviourExtended.LogWarning("There are multiple " + typeof(T).Name + " in the scene!"); } base.Awake(); } protected void OnDestroy() { instances.Remove(typeof(T)); } }