選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

197 行
7.2 KiB

  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.SceneManagement;
  4. namespace SUISS.Core
  5. {
  6. public class SingletonMonobehaviour<T> : MonoBehaviour where T : SingletonMonobehaviour<T>
  7. {
  8. protected virtual void Awake()
  9. {
  10. SingletonMonobehaviour<T>.applicationIsQuitting = false;
  11. SingletonMonobehaviour<T>.quitWarningShown = false;
  12. if (SingletonMonobehaviour<T>._instance == this)
  13. {
  14. UnityEngine.Debug.Log(string.Format("[Singleton] I'm {0}, already the instance. Not executing Awake again.", base.name));
  15. return;
  16. }
  17. if (SingletonMonobehaviour<T>._instance != null)
  18. {
  19. if (!this._overrideOldInstance)
  20. {
  21. this._isValidNewInstance = false;
  22. this.DestroyInstanceObject((T)((object)this));
  23. UnityEngine.Debug.LogWarning(string.Format("[Singleton] There already exists a {0} singleton. Instance will be kept with old, be carefull that enherited classes might reset other values in Awake or it's constructor. Instance on object {1} is removed.", typeof(T), base.gameObject.name));
  24. return;
  25. }
  26. SingletonMonobehaviour<T>._instance._isValidNewInstance = false;
  27. bool flag = this.DestroyInstanceObject(SingletonMonobehaviour<T>._instance);
  28. UnityEngine.Debug.LogWarning(string.Format("[Singleton] There already exists a {0} singleton. New instance is used because it has been flagged as ForceUse. {1}", typeof(T), (!flag) ? string.Empty : " Old gameobject has been destroyed."));
  29. }
  30. SingletonMonobehaviour<T>._instance = (T)((object)this);
  31. if (PersistentManager.HasAttribute(typeof(T)))
  32. {
  33. if (base.transform.parent != null)
  34. {
  35. UnityEngine.Debug.LogWarning("Please don't parent any singletons with marked as DontDestroyOnLoad, as we can't promise the DontDestroyOnLoad functionality then.");
  36. }
  37. UnityEngine.Object.DontDestroyOnLoad(this);
  38. }
  39. }
  40. public static T InstanceIfAvailable
  41. {
  42. get
  43. {
  44. return (!SingletonMonobehaviour<T>.IsAvailable) ? ((T)((object)null)) : SingletonMonobehaviour<T>.Instance;
  45. }
  46. }
  47. public static T Instance
  48. {
  49. get
  50. {
  51. if (!object.ReferenceEquals(SingletonMonobehaviour<T>._instance, null))
  52. {
  53. return SingletonMonobehaviour<T>._instance;
  54. }
  55. if (SingletonMonobehaviour<T>.applicationIsQuitting)
  56. {
  57. if (!SingletonMonobehaviour<T>.quitWarningShown)
  58. {
  59. UnityEngine.Debug.LogWarning(string.Format("[Singleton] Instance '{0}' already destroyed on application quit. Won't create again - returning null.", typeof(T)));
  60. SingletonMonobehaviour<T>.quitWarningShown = true;
  61. }
  62. return (T)((object)null);
  63. }
  64. object @lock = SingletonMonobehaviour<T>._lock;
  65. T instance;
  66. lock (@lock)
  67. {
  68. if (SingletonMonobehaviour<T>._instance == null)
  69. {
  70. SingletonMonobehaviour<T>._instance = (T)((object)UnityEngine.Object.FindObjectOfType(typeof(T)));
  71. if (UnityEngine.Object.FindObjectsOfType(typeof(T)).Length > 1)
  72. {
  73. UnityEngine.Debug.LogError("[Singleton] Something went really wrong - there should never be more than 1 singleton! Reopenning the scene might fix it.");
  74. return SingletonMonobehaviour<T>._instance;
  75. }
  76. if (PersistentManager.HasAttribute(typeof(T)))
  77. {
  78. if (PersistentManager.SceneWasLoaded)
  79. {
  80. UnityEngine.Debug.LogWarning("[Singleton] PersistentManagers scene was already loaded.");
  81. }
  82. else
  83. {
  84. bool flag = true;
  85. if (SceneManager.GetSceneByName("PersistentManagers").IsValid())
  86. {
  87. SceneManager.LoadScene("PersistentManagers", LoadSceneMode.Additive);
  88. }
  89. else
  90. {
  91. UnityEngine.Debug.LogWarning(typeof(T).ToString() + "'s attribute [PersistentManager] wants a PersistentManagers scene, but its not in the build settings! Will create a DontDestroyOnLoad object now. Please remove the attribute or implement it correctly (PersistentManager scene)");
  92. flag = false;
  93. }
  94. PersistentManager.SceneWasLoaded = true;
  95. SingletonMonobehaviour<T>._instance = (T)((object)UnityEngine.Object.FindObjectOfType(typeof(T)));
  96. if (SingletonMonobehaviour<T>._instance == null && flag)
  97. {
  98. UnityEngine.Debug.LogWarning(string.Format("[Singleton] Loading of PersistentManagers scene did not create instance of {0}.", typeof(T)));
  99. }
  100. }
  101. }
  102. if (SingletonMonobehaviour<T>._instance == null)
  103. {
  104. GameObject gameObject = new GameObject();
  105. SingletonMonobehaviour<T>._instance = gameObject.AddComponent<T>();
  106. gameObject.name = string.Format("(singleton) {0}", typeof(T).ToString());
  107. if (PersistentManager.HasAttribute(typeof(T)))
  108. {
  109. UnityEngine.Object.DontDestroyOnLoad(gameObject);
  110. }
  111. if (!PersistentManager.IsLoadAtRuntime(typeof(T)))
  112. {
  113. UnityEngine.Debug.LogError(string.Format("[Singleton] An instance of {0} is needed in the scene, so '{1}' was created{2}.", typeof(T), gameObject, (!PersistentManager.HasAttribute(typeof(T))) ? string.Empty : " with DontDestroyOnLoad"));
  114. }
  115. }
  116. else
  117. {
  118. UnityEngine.Debug.Log(string.Format("[Singleton] Using instance already created: {0}", SingletonMonobehaviour<T>._instance.gameObject.name));
  119. }
  120. }
  121. instance = SingletonMonobehaviour<T>._instance;
  122. }
  123. return instance;
  124. }
  125. }
  126. [Obsolete("Instead of using this, call Instance on the type you want.")]
  127. public static S InstanceAs<S>() where S : T
  128. {
  129. T instance = SingletonMonobehaviour<T>.Instance;
  130. if (instance is S)
  131. {
  132. return instance as S;
  133. }
  134. UnityEngine.Debug.LogError(string.Format("[Singleton] Instance of type {0} is not assignable to type {1}", (!(instance == null)) ? instance.GetType().Name : "null", typeof(S)));
  135. return (S)((object)null);
  136. }
  137. public static bool IsAvailable
  138. {
  139. get
  140. {
  141. return SingletonMonobehaviour<T>._instance != null;
  142. }
  143. }
  144. protected virtual void OnApplicationQuit()
  145. {
  146. SingletonMonobehaviour<T>.applicationIsQuitting = true;
  147. SingletonMonobehaviour<T>.quitWarningShown = false;
  148. }
  149. protected virtual void OnDestroy()
  150. {
  151. if (!this._isValidNewInstance)
  152. {
  153. return;
  154. }
  155. if (SingletonMonobehaviour<T>._instance == null)
  156. {
  157. UnityEngine.Debug.LogWarning(string.Format("[Singleton] instance of {0} singleton already is null in OnDestroy", typeof(T)));
  158. }
  159. SingletonMonobehaviour<T>._instance = (T)((object)null);
  160. }
  161. private bool DestroyInstanceObject(T instance)
  162. {
  163. GameObject gameObject = instance.gameObject;
  164. UnityEngine.Object.Destroy(instance);
  165. bool result = false;
  166. if (gameObject.transform.childCount == 0 && gameObject.GetComponents<Component>().Length <= 2)
  167. {
  168. UnityEngine.Object.Destroy(gameObject);
  169. result = true;
  170. }
  171. return result;
  172. }
  173. private static T _instance = (T)((object)null);
  174. private static object _lock = new object();
  175. private static bool quitWarningShown = false;
  176. [SerializeField]
  177. [Tooltip("Use this instance for the entire game cycle, even when someone with the same flag wants to become the instance")]
  178. protected bool _overrideOldInstance;
  179. protected bool _isValidNewInstance = true;
  180. private static bool applicationIsQuitting = false;
  181. }
  182. }