Singleton.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using UnityEngine;
  2. namespace Chronos
  3. {
  4. public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
  5. {
  6. private static T _instance;
  7. private static object _lock = new object();
  8. private static bool destroyed = false;
  9. private static bool persistent = false;
  10. private static bool automatic = false;
  11. private static bool missing = false;
  12. public static bool instantiated
  13. {
  14. get { return !missing && !destroyed && _instance != null; }
  15. }
  16. public static T instance
  17. {
  18. get
  19. {
  20. if (!Application.isPlaying)
  21. {
  22. T[] instances = FindObjectsOfType<T>();
  23. if (instances.Length == 1)
  24. {
  25. _instance = instances[0];
  26. }
  27. else if (instances.Length == 0)
  28. {
  29. throw new UnityException("Missing '" + typeof(T) + "' singleton in the scene.");
  30. }
  31. else if (instances.Length > 1)
  32. {
  33. throw new UnityException("More than one '" + typeof(T) + "' singleton in the scene.");
  34. }
  35. }
  36. if (destroyed)
  37. {
  38. return null;
  39. }
  40. if (missing)
  41. {
  42. throw new UnityException("Missing '" + typeof(T) + "' singleton in the scene.");
  43. }
  44. lock (_lock)
  45. {
  46. if (_instance == null)
  47. {
  48. T[] instances = FindObjectsOfType<T>();
  49. if (instances.Length == 1)
  50. {
  51. _instance = instances[0];
  52. }
  53. else if (instances.Length == 0)
  54. {
  55. GameObject singleton = new GameObject();
  56. _instance = singleton.AddComponent<T>();
  57. if (!automatic)
  58. {
  59. Destroy(singleton);
  60. missing = true;
  61. throw new UnityException("Missing '" + typeof(T) + "' singleton in the scene.");
  62. }
  63. singleton.name = "(singleton) " + typeof(T).ToString();
  64. if (persistent)
  65. {
  66. DontDestroyOnLoad(singleton);
  67. }
  68. }
  69. else if (instances.Length > 1)
  70. {
  71. throw new UnityException("More than one '" + typeof(T) + "' singleton in the scene.");
  72. }
  73. }
  74. return _instance;
  75. }
  76. }
  77. }
  78. protected virtual void OnDestroy()
  79. {
  80. if (persistent)
  81. {
  82. destroyed = true;
  83. }
  84. }
  85. protected Singleton(bool persistent, bool automatic)
  86. {
  87. Singleton<T>.persistent = persistent;
  88. Singleton<T>.automatic = automatic;
  89. }
  90. }
  91. }