CFX_SpawnSystem.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. // Cartoon FX - (c) 2013, Jean Moreno
  5. // Spawn System:
  6. // Preload GameObject to reuse them later, avoiding to Instantiate them.
  7. // Very useful for mobile platforms.
  8. public class CFX_SpawnSystem : MonoBehaviour
  9. {
  10. /// <summary>
  11. /// Get the next available preloaded Object.
  12. /// </summary>
  13. /// <returns>
  14. /// The next available preloaded Object.
  15. /// </returns>
  16. /// <param name='sourceObj'>
  17. /// The source Object from which to get a preloaded copy.
  18. /// </param>
  19. /// <param name='activateObject'>
  20. /// Activates the object before returning it.
  21. /// </param>
  22. static public GameObject GetNextObject(GameObject sourceObj, bool activateObject = true)
  23. {
  24. int uniqueId = sourceObj.GetInstanceID();
  25. if(!instance.poolCursors.ContainsKey(uniqueId))
  26. {
  27. Debug.LogError("[CFX_SpawnSystem.GetNextPoolObject()] Object hasn't been preloaded: " + sourceObj.name + " (ID:" + uniqueId + ")");
  28. return null;
  29. }
  30. int cursor = instance.poolCursors[uniqueId];
  31. instance.poolCursors[uniqueId]++;
  32. if(instance.poolCursors[uniqueId] >= instance.instantiatedObjects[uniqueId].Count)
  33. {
  34. instance.poolCursors[uniqueId] = 0;
  35. }
  36. GameObject returnObj = instance.instantiatedObjects[uniqueId][cursor];
  37. if(activateObject)
  38. #if UNITY_3_5
  39. returnObj.SetActiveRecursively(true);
  40. #else
  41. returnObj.SetActive(true);
  42. #endif
  43. return returnObj;
  44. }
  45. /// <summary>
  46. /// Preloads an object a number of times in the pool.
  47. /// </summary>
  48. /// <param name='sourceObj'>
  49. /// The source Object.
  50. /// </param>
  51. /// <param name='poolSize'>
  52. /// The number of times it will be instantiated in the pool (i.e. the max number of same object that would appear simultaneously in your Scene).
  53. /// </param>
  54. static public void PreloadObject(GameObject sourceObj, int poolSize = 1)
  55. {
  56. instance.addObjectToPool(sourceObj, poolSize);
  57. }
  58. /// <summary>
  59. /// Unloads all the preloaded objects from a source Object.
  60. /// </summary>
  61. /// <param name='sourceObj'>
  62. /// Source object.
  63. /// </param>
  64. static public void UnloadObjects(GameObject sourceObj)
  65. {
  66. instance.removeObjectsFromPool(sourceObj);
  67. }
  68. /// <summary>
  69. /// Gets a value indicating whether all objects defined in the Editor are loaded or not.
  70. /// </summary>
  71. /// <value>
  72. /// <c>true</c> if all objects are loaded; otherwise, <c>false</c>.
  73. /// </value>
  74. static public bool AllObjectsLoaded
  75. {
  76. get
  77. {
  78. return instance.allObjectsLoaded;
  79. }
  80. }
  81. // INTERNAL SYSTEM ----------------------------------------------------------------------------------------------------------------------------------------
  82. static private CFX_SpawnSystem instance;
  83. public GameObject[] objectsToPreload = new GameObject[0];
  84. public int[] objectsToPreloadTimes = new int[0];
  85. public bool hideObjectsInHierarchy;
  86. private bool allObjectsLoaded;
  87. private Dictionary<int,List<GameObject>> instantiatedObjects = new Dictionary<int, List<GameObject>>();
  88. private Dictionary<int,int> poolCursors = new Dictionary<int, int>();
  89. private void addObjectToPool(GameObject sourceObject, int number)
  90. {
  91. int uniqueId = sourceObject.GetInstanceID();
  92. //Add new entry if it doesn't exist
  93. if(!instantiatedObjects.ContainsKey(uniqueId))
  94. {
  95. instantiatedObjects.Add(uniqueId, new List<GameObject>());
  96. poolCursors.Add(uniqueId, 0);
  97. }
  98. //Add the new objects
  99. GameObject newObj;
  100. for(int i = 0; i < number; i++)
  101. {
  102. newObj = (GameObject)Instantiate(sourceObject);
  103. #if UNITY_3_5
  104. newObj.SetActiveRecursively(false);
  105. #else
  106. newObj.SetActive(false);
  107. #endif
  108. //Set flag to not destruct object
  109. CFX_AutoDestructShuriken[] autoDestruct = newObj.GetComponentsInChildren<CFX_AutoDestructShuriken>(true);
  110. foreach(CFX_AutoDestructShuriken ad in autoDestruct)
  111. {
  112. ad.OnlyDeactivate = true;
  113. }
  114. //Set flag to not destruct light
  115. CFX_LightIntensityFade[] lightIntensity = newObj.GetComponentsInChildren<CFX_LightIntensityFade>(true);
  116. foreach(CFX_LightIntensityFade li in lightIntensity)
  117. {
  118. li.autodestruct = false;
  119. }
  120. instantiatedObjects[uniqueId].Add(newObj);
  121. if(hideObjectsInHierarchy)
  122. newObj.hideFlags = HideFlags.HideInHierarchy;
  123. }
  124. }
  125. private void removeObjectsFromPool(GameObject sourceObject)
  126. {
  127. int uniqueId = sourceObject.GetInstanceID();
  128. if(!instantiatedObjects.ContainsKey(uniqueId))
  129. {
  130. Debug.LogWarning("[CFX_SpawnSystem.removeObjectsFromPool()] There aren't any preloaded object for: " + sourceObject.name + " (ID:" + uniqueId + ")");
  131. return;
  132. }
  133. //Destroy all objects
  134. for(int i = instantiatedObjects[uniqueId].Count - 1; i >= 0; i--)
  135. {
  136. GameObject obj = instantiatedObjects[uniqueId][i];
  137. instantiatedObjects[uniqueId].RemoveAt(i);
  138. GameObject.Destroy(obj);
  139. }
  140. //Remove pool entry
  141. instantiatedObjects.Remove(uniqueId);
  142. poolCursors.Remove(uniqueId);
  143. }
  144. void Awake()
  145. {
  146. if(instance != null)
  147. Debug.LogWarning("CFX_SpawnSystem: There should only be one instance of CFX_SpawnSystem per Scene!");
  148. instance = this;
  149. }
  150. void Start()
  151. {
  152. allObjectsLoaded = false;
  153. for(int i = 0; i < objectsToPreload.Length; i++)
  154. {
  155. PreloadObject(objectsToPreload[i], objectsToPreloadTimes[i]);
  156. }
  157. allObjectsLoaded = true;
  158. }
  159. }