using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using YooAsset; namespace UniFramework.Pooling { public class Spawner { private readonly List _gameObjectPools = new List(100); private readonly List _removeList = new List(100); private readonly GameObject _spawnerRoot; private readonly ResourcePackage _package; public string PackageName { get { return _package.PackageName; } } private Spawner() { } internal Spawner(GameObject poolingRoot, ResourcePackage package) { _spawnerRoot = new GameObject($"{package.PackageName}"); _spawnerRoot.transform.SetParent(poolingRoot.transform); _package = package; } /// /// 更新游戏对象池系统 /// internal void Update() { _removeList.Clear(); foreach (var pool in _gameObjectPools) { if (pool.CanAutoDestroy()) _removeList.Add(pool); } foreach (var pool in _removeList) { _gameObjectPools.Remove(pool); pool.DestroyPool(); } } /// /// 销毁游戏对象池系统 /// internal void Destroy() { DestroyAll(true); } /// /// 销毁所有对象池及其资源 /// /// 销毁所有对象池,包括常驻对象池 public void DestroyAll(bool includeAll) { if (includeAll) { foreach (var pool in _gameObjectPools) { pool.DestroyPool(); } _gameObjectPools.Clear(); } else { List removeList = new List(); foreach (var pool in _gameObjectPools) { if (pool.DontDestroy == false) removeList.Add(pool); } foreach (var pool in removeList) { _gameObjectPools.Remove(pool); pool.DestroyPool(); } } } /// /// 异步创建指定资源的游戏对象池 /// /// 资源定位地址 /// 资源常驻不销毁 /// 对象池的初始容量 /// 对象池的最大容量 /// 静默销毁时间(注意:小于零代表不主动销毁) public CreatePoolOperation CreateGameObjectPoolAsync(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f) { return CreateGameObjectPoolInternal(location, dontDestroy, initCapacity, maxCapacity, destroyTime); } /// /// 同步创建指定资源的游戏对象池 /// /// 资源定位地址 /// 资源常驻不销毁 /// 对象池的初始容量 /// 对象池的最大容量 /// 静默销毁时间(注意:小于零代表不主动销毁) public CreatePoolOperation CreateGameObjectPoolSync(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f) { var operation = CreateGameObjectPoolInternal(location, dontDestroy, initCapacity, maxCapacity, destroyTime); operation.WaitForAsyncComplete(); return operation; } /// /// 创建指定资源的游戏对象池 /// private CreatePoolOperation CreateGameObjectPoolInternal(string location, bool dontDestroy = false, int initCapacity = 0, int maxCapacity = int.MaxValue, float destroyTime = -1f) { if (maxCapacity < initCapacity) throw new Exception("The max capacity value must be greater the init capacity value."); GameObjectPool pool = TryGetGameObjectPool(location); if (pool != null) { UniLogger.Warning($"GameObject pool is already existed : {location}"); var operation = new CreatePoolOperation(pool.AssetHandle); YooAssets.StartOperation(operation); return operation; } else { pool = new GameObjectPool(_spawnerRoot, location, dontDestroy, initCapacity, maxCapacity, destroyTime); pool.CreatePool(_package); _gameObjectPools.Add(pool); var operation = new CreatePoolOperation(pool.AssetHandle); YooAssets.StartOperation(operation); return operation; } } /// /// 异步实例化一个游戏对象 /// /// 资源定位地址 /// 强制克隆游戏对象,忽略缓存池里的对象 /// 用户自定义数据 public SpawnHandle SpawnAsync(string location, bool forceClone = false, params System.Object[] userDatas) { return SpawnInternal(location, null, Vector3.zero, Quaternion.identity, forceClone, userDatas); } /// /// 异步实例化一个游戏对象 /// /// 资源定位地址 /// 父物体 /// 强制克隆游戏对象,忽略缓存池里的对象 /// 用户自定义数据 public SpawnHandle SpawnAsync(string location, Transform parent, bool forceClone = false, params System.Object[] userDatas) { return SpawnInternal(location, parent, Vector3.zero, Quaternion.identity, forceClone, userDatas); } /// /// 异步实例化一个游戏对象 /// /// 资源定位地址 /// 父物体 /// 世界坐标 /// 世界角度 /// 强制克隆游戏对象,忽略缓存池里的对象 /// 用户自定义数据 public SpawnHandle SpawnAsync(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone = false, params System.Object[] userDatas) { return SpawnInternal(location, parent, position, rotation, forceClone, userDatas); } /// /// 同步实例化一个游戏对象 /// /// 资源定位地址 /// 强制克隆游戏对象,忽略缓存池里的对象 /// 用户自定义数据 public SpawnHandle SpawnSync(string location, bool forceClone = false, params System.Object[] userDatas) { SpawnHandle handle = SpawnInternal(location, null, Vector3.zero, Quaternion.identity, forceClone, userDatas); handle.WaitForAsyncComplete(); return handle; } /// /// 同步实例化一个游戏对象 /// /// 资源定位地址 /// 父物体 /// 强制克隆游戏对象,忽略缓存池里的对象 /// 用户自定义数据 public SpawnHandle SpawnSync(string location, Transform parent, bool forceClone = false, params System.Object[] userDatas) { SpawnHandle handle = SpawnInternal(location, parent, Vector3.zero, Quaternion.identity, forceClone, userDatas); handle.WaitForAsyncComplete(); return handle; } /// /// 同步实例化一个游戏对象 /// /// 资源定位地址 /// 父物体 /// 世界坐标 /// 世界角度 /// 强制克隆游戏对象,忽略缓存池里的对象 /// 用户自定义数据 public SpawnHandle SpawnSync(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone = false, params System.Object[] userDatas) { SpawnHandle handle = SpawnInternal(location, parent, position, rotation, forceClone, userDatas); handle.WaitForAsyncComplete(); return handle; } /// /// 实例化一个游戏对象 /// private SpawnHandle SpawnInternal(string location, Transform parent, Vector3 position, Quaternion rotation, bool forceClone, params System.Object[] userDatas) { var pool = TryGetGameObjectPool(location); if (pool != null) { return pool.Spawn(parent, position, rotation, forceClone, userDatas); } // 如果不存在创建游戏对象池 pool = new GameObjectPool(_spawnerRoot, location, false, 0, int.MaxValue, -1f); pool.CreatePool(_package); _gameObjectPools.Add(pool); return pool.Spawn(parent, position, rotation, forceClone, userDatas); } private GameObjectPool TryGetGameObjectPool(string location) { foreach (var pool in _gameObjectPools) { if (pool.Location == location) return pool; } return null; } } }