Spawner.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using YooAsset;
  6. namespace UniFramework.Pooling
  7. {
  8. public class Spawner
  9. {
  10. private readonly List<GameObjectPool> _gameObjectPools = new List<GameObjectPool>(100);
  11. private readonly List<GameObjectPool> _removeList = new List<GameObjectPool>(100);
  12. private readonly GameObject _spawnerRoot;
  13. private readonly ResourcePackage _package;
  14. public string PackageName
  15. {
  16. get
  17. {
  18. return _package.PackageName;
  19. }
  20. }
  21. private Spawner()
  22. {
  23. }
  24. internal Spawner(GameObject poolingRoot, ResourcePackage package)
  25. {
  26. _spawnerRoot = new GameObject($"{package.PackageName}");
  27. _spawnerRoot.transform.SetParent(poolingRoot.transform);
  28. _package = package;
  29. }
  30. /// <summary>
  31. /// 更新游戏对象池系统
  32. /// </summary>
  33. internal void Update()
  34. {
  35. _removeList.Clear();
  36. foreach (var pool in _gameObjectPools)
  37. {
  38. if (pool.CanAutoDestroy())
  39. _removeList.Add(pool);
  40. }
  41. foreach (var pool in _removeList)
  42. {
  43. _gameObjectPools.Remove(pool);
  44. pool.DestroyPool();
  45. }
  46. }
  47. /// <summary>
  48. /// 销毁游戏对象池系统
  49. /// </summary>
  50. internal void Destroy()
  51. {
  52. DestroyAll(true);
  53. }
  54. /// <summary>
  55. /// 销毁所有对象池及其资源
  56. /// </summary>
  57. /// <param name="includeAll">销毁所有对象池,包括常驻对象池</param>
  58. public void DestroyAll(bool includeAll)
  59. {
  60. if (includeAll)
  61. {
  62. foreach (var pool in _gameObjectPools)
  63. {
  64. pool.DestroyPool();
  65. }
  66. _gameObjectPools.Clear();
  67. }
  68. else
  69. {
  70. List<GameObjectPool> removeList = new List<GameObjectPool>();
  71. foreach (var pool in _gameObjectPools)
  72. {
  73. if (pool.DontDestroy == false)
  74. removeList.Add(pool);
  75. }
  76. foreach (var pool in removeList)
  77. {
  78. _gameObjectPools.Remove(pool);
  79. pool.DestroyPool();
  80. }
  81. }
  82. }
  83. /// <summary>
  84. /// 异步创建指定资源的游戏对象池
  85. /// </summary>
  86. /// <param name="location">资源定位地址</param>
  87. /// <param name="dontDestroy">资源常驻不销毁</param>
  88. /// <param name="initCapacity">对象池的初始容量</param>
  89. /// <param name="maxCapacity">对象池的最大容量</param>
  90. /// <param name="destroyTime">静默销毁时间(注意:小于零代表不主动销毁)</param>
  91. public CreatePoolOperation CreateGameObjectPoolAsync(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f)
  92. {
  93. return CreateGameObjectPoolInternal(location, dontDestroy, initCapacity, maxCapacity, destroyTime);
  94. }
  95. /// <summary>
  96. /// 同步创建指定资源的游戏对象池
  97. /// </summary>
  98. /// <param name="location">资源定位地址</param>
  99. /// <param name="dontDestroy">资源常驻不销毁</param>
  100. /// <param name="initCapacity">对象池的初始容量</param>
  101. /// <param name="maxCapacity">对象池的最大容量</param>
  102. /// <param name="destroyTime">静默销毁时间(注意:小于零代表不主动销毁)</param>
  103. public CreatePoolOperation CreateGameObjectPoolSync(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f)
  104. {
  105. var operation = CreateGameObjectPoolInternal(location, dontDestroy, initCapacity, maxCapacity, destroyTime);
  106. operation.WaitForAsyncComplete();
  107. return operation;
  108. }
  109. /// <summary>
  110. /// 创建指定资源的游戏对象池
  111. /// </summary>
  112. private CreatePoolOperation CreateGameObjectPoolInternal(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f)
  113. {
  114. if (maxCapacity < initCapacity)
  115. throw new Exception("The max capacity value must be greater the init capacity value.");
  116. GameObjectPool pool = TryGetGameObjectPool(location);
  117. if (pool != null)
  118. {
  119. UniLogger.Warning($"GameObject pool is already existed : {location}");
  120. var operation = new CreatePoolOperation(pool.AssetHandle);
  121. YooAssets.StartOperation(operation);
  122. return operation;
  123. }
  124. else
  125. {
  126. pool = new GameObjectPool(_spawnerRoot, location, dontDestroy, initCapacity, maxCapacity, destroyTime);
  127. pool.CreatePool(_package);
  128. _gameObjectPools.Add(pool);
  129. var operation = new CreatePoolOperation(pool.AssetHandle);
  130. YooAssets.StartOperation(operation);
  131. return operation;
  132. }
  133. }
  134. /// <summary>
  135. /// 异步实例化一个游戏对象
  136. /// </summary>
  137. /// <param name="location">资源定位地址</param>
  138. /// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
  139. /// <param name="userDatas">用户自定义数据</param>
  140. public SpawnHandle SpawnAsync(string location, bool forceClone = false, params System.Object[] userDatas)
  141. {
  142. return SpawnInternal(location, null, Vector3.zero, Quaternion.identity, forceClone, userDatas);
  143. }
  144. /// <summary>
  145. /// 异步实例化一个游戏对象
  146. /// </summary>
  147. /// <param name="location">资源定位地址</param>
  148. /// <param name="parent">父物体</param>
  149. /// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
  150. /// <param name="userDatas">用户自定义数据</param>
  151. public SpawnHandle SpawnAsync(string location, Transform parent, bool forceClone = false, params System.Object[] userDatas)
  152. {
  153. return SpawnInternal(location, parent, Vector3.zero, Quaternion.identity, forceClone, userDatas);
  154. }
  155. /// <summary>
  156. /// 异步实例化一个游戏对象
  157. /// </summary>
  158. /// <param name="location">资源定位地址</param>
  159. /// <param name="parent">父物体</param>
  160. /// <param name="position">世界坐标</param>
  161. /// <param name="rotation">世界角度</param>
  162. /// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
  163. /// <param name="userDatas">用户自定义数据</param>
  164. public SpawnHandle SpawnAsync(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone = false, params System.Object[] userDatas)
  165. {
  166. return SpawnInternal(location, parent, position, rotation, forceClone, userDatas);
  167. }
  168. /// <summary>
  169. /// 同步实例化一个游戏对象
  170. /// </summary>
  171. /// <param name="location">资源定位地址</param>
  172. /// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
  173. /// <param name="userDatas">用户自定义数据</param>
  174. public SpawnHandle SpawnSync(string location, bool forceClone = false, params System.Object[] userDatas)
  175. {
  176. SpawnHandle handle = SpawnInternal(location, null, Vector3.zero, Quaternion.identity, forceClone, userDatas);
  177. handle.WaitForAsyncComplete();
  178. return handle;
  179. }
  180. /// <summary>
  181. /// 同步实例化一个游戏对象
  182. /// </summary>
  183. /// <param name="location">资源定位地址</param>
  184. /// <param name="parent">父物体</param>
  185. /// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
  186. /// <param name="userDatas">用户自定义数据</param>
  187. public SpawnHandle SpawnSync(string location, Transform parent, bool forceClone = false, params System.Object[] userDatas)
  188. {
  189. SpawnHandle handle = SpawnInternal(location, parent, Vector3.zero, Quaternion.identity, forceClone, userDatas);
  190. handle.WaitForAsyncComplete();
  191. return handle;
  192. }
  193. /// <summary>
  194. /// 同步实例化一个游戏对象
  195. /// </summary>
  196. /// <param name="location">资源定位地址</param>
  197. /// <param name="parent">父物体</param>
  198. /// <param name="position">世界坐标</param>
  199. /// <param name="rotation">世界角度</param>
  200. /// <param name="forceClone">强制克隆游戏对象,忽略缓存池里的对象</param>
  201. /// <param name="userDatas">用户自定义数据</param>
  202. public SpawnHandle SpawnSync(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone = false, params System.Object[] userDatas)
  203. {
  204. SpawnHandle handle = SpawnInternal(location, parent, position, rotation, forceClone, userDatas);
  205. handle.WaitForAsyncComplete();
  206. return handle;
  207. }
  208. /// <summary>
  209. /// 实例化一个游戏对象
  210. /// </summary>
  211. private SpawnHandle SpawnInternal(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone, params System.Object[] userDatas)
  212. {
  213. var pool = TryGetGameObjectPool(location);
  214. if (pool != null)
  215. {
  216. return pool.Spawn(parent, position, rotation, forceClone, userDatas);
  217. }
  218. // 如果不存在创建游戏对象池
  219. pool = new GameObjectPool(_spawnerRoot, location, false, 0, int.MaxValue, -1f);
  220. pool.CreatePool(_package);
  221. _gameObjectPools.Add(pool);
  222. return pool.Spawn(parent, position, rotation, forceClone, userDatas);
  223. }
  224. private GameObjectPool TryGetGameObjectPool(string location)
  225. {
  226. foreach (var pool in _gameObjectPools)
  227. {
  228. if (pool.Location == location)
  229. return pool;
  230. }
  231. return null;
  232. }
  233. //扩展
  234. public bool IsGameObjectPoolExisted(string location)
  235. {
  236. return TryGetGameObjectPool(location) != null;
  237. }
  238. }
  239. }