SRAutoSingleton.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. namespace SRF.Components
  2. {
  3. using System.Diagnostics;
  4. using UnityEngine;
  5. using Debug = UnityEngine.Debug;
  6. /// <summary>
  7. /// Singleton MonoBehaviour class which automatically creates an instance if one does not already exist.
  8. /// </summary>
  9. public abstract class SRAutoSingleton<T> : SRMonoBehaviour where T : SRAutoSingleton<T>
  10. {
  11. private static T _instance;
  12. /// <summary>
  13. /// Get (or create) the instance of this Singleton
  14. /// </summary>
  15. public static T Instance
  16. {
  17. [DebuggerStepThrough]
  18. get
  19. {
  20. // Instance required for the first time, we look for it
  21. if (_instance == null && Application.isPlaying)
  22. {
  23. #if UNITY_EDITOR
  24. // Support reloading scripts after a recompile - static reference will be cleared, but we can find it again.
  25. T autoSingleton = FindObjectOfType<T>();
  26. if (autoSingleton != null)
  27. {
  28. _instance = autoSingleton;
  29. return _instance;
  30. }
  31. #endif
  32. var go = new GameObject("_" + typeof (T).Name);
  33. go.AddComponent<T>(); // _instance set by Awake() constructor
  34. }
  35. return _instance;
  36. }
  37. }
  38. public static bool HasInstance
  39. {
  40. get { return _instance != null; }
  41. }
  42. // If no other monobehaviour request the instance in an awake function
  43. // executing before this one, no need to search the object.
  44. protected virtual void Awake()
  45. {
  46. if (_instance != null)
  47. {
  48. Debug.LogWarning("More than one singleton object of type {0} exists.".Fmt(typeof (T).Name));
  49. return;
  50. }
  51. _instance = (T) this;
  52. }
  53. protected virtual void OnEnable()
  54. {
  55. #if UNITY_EDITOR
  56. // Restore reference after C# recompile.
  57. _instance = (T) this;
  58. #endif
  59. }
  60. // Make sure the instance isn't referenced anymore when the user quit, just in case.
  61. private void OnApplicationQuit()
  62. {
  63. _instance = null;
  64. }
  65. }
  66. }