using System; using System.Collections; using System.Collections.Generic; using PathologicalGames; using UnityEngine; using Object = UnityEngine.Object; namespace ET { public class GameObjectPoolAwakeSystem : AwakeSystem { public override void Awake(GameObjectPool self) { GameObjectPool.Instanse = self; self.Awake(); } } public class GameObjectPoolDestroySystem : DestroySystem { public override void Destroy(GameObjectPool self) { self.Destroy(); } } public class GameObjectPool : Entity { public static GameObjectPool Instanse; /// /// 游戏物体对象池字典 /// private Dictionary m_SpawnPoolDic; /// /// 实例ID对应对象池Id /// private Dictionary m_InstanceIdPoolDic; /// /// 空闲预设池队列 /// private Queue m_PrefabPoolQueue; public void Awake() { m_SpawnPoolDic = new Dictionary(); m_InstanceIdPoolDic = new Dictionary(); m_PrefabPoolQueue = new Queue(); InstanceHandler.InstantiateDelegates += this.InstantiateDelegate; InstanceHandler.DestroyDelegates += this.DestroyDelegate; Init(UnityRoot.Instance.GameObjectPoolGroups, UnityRoot.Instance.ObjPoolParent); } /// /// 对象池物体创建回调 /// /// /// /// /// /// private GameObject InstantiateDelegate(GameObject prefab, Vector3 pos, Quaternion rot, object userData) { ResourceEntity resourceEntity = userData as ResourceEntity; if (resourceEntity == null) { Log.Error("资源信息不存在 resourceEntity=" + resourceEntity.ResourceName); return null; } GameObject obj = UnityEngine.Object.Instantiate(prefab, pos, rot) as GameObject; //注册 //Game.Scene.GetComponent().RegistInstanceResource(obj.GetInstanceID(), resourceEntity); resourceEntity.Dispose(); return obj; } /// /// 对象池物体销毁回调 /// /// private void DestroyDelegate(GameObject instance) { UnityEngine.Object.Destroy(instance); //Game.Scene.GetComponent()?.ResourceLoaderComponent.UnloadGameObject(instance); } /// /// 物体对象池的初始化 /// /// /// /// public void Init(GameObjectPoolEntity[] arr, Transform parent) { int len = arr.Length; for (int i = 0; i < len; i++) { GameObjectPoolEntity entity = arr[i]; if (entity.Pool != null) { Destroy(entity); } //创建对象池 SpawnPool pool = PathologicalGames.PoolManager.Pools.Create(entity.PoolName); pool.group.parent = parent; pool.group.localPosition = Vector3.zero; entity.Pool = pool; m_SpawnPoolDic[entity.PoolId] = entity; } } private void Destroy(GameObjectPoolEntity entity) { UnityEngine.Object.Destroy(entity.Pool.gameObject); entity.Pool = null; } public async ETTask> GameObjectSpawn(int id, byte poolId, string path, bool cullDespawned, int cullAbove, int cullDelay, int cullMaxPerPass) { return await Spawn(id, poolId, path, cullDespawned, cullAbove, cullDelay, cullMaxPerPass); } /// /// 对象回池 /// /// public void GameObjectDespawn(Transform instance) { Despawn(instance); } #region Spawn /// /// 从对象池中获取对象 /// /// /// public async ETTask> Spawn(int id, byte poolId, string path, bool cullDespawned, int cullAbove, int cullDelay, int cullMaxPerPass) { //using (await Game.Scene.GetComponent().Wait(CoroutineLockType.ResourcesLoader, 10000)) //{ GameObjectPoolEntity gameObjectPoolEntity = m_SpawnPoolDic[poolId]; //使用预设编号 当做池ID PrefabPool prefabPool = gameObjectPoolEntity.Pool.GetPrefabPool(id); if (prefabPool != null) { //拿到一个实例 Transform retTrans = prefabPool.TrySpawnInstance(); if (retTrans != null) { int instanceID = retTrans.gameObject.GetInstanceID(); m_InstanceIdPoolDic[instanceID] = poolId; return (retTrans, false); } } GameObject go = await ResourceHelper.LoadAssetAsync(path); ResourceEntity resEntity = EntityFactory.Create(Game.Scene); resEntity.Target = go; resEntity.ResourceName = path; Transform prefab = go.transform; prefabPool = gameObjectPoolEntity.Pool.GetPrefabPool(id); if (prefabPool == null) { //先去队列里面找空闲的池 if (m_PrefabPoolQueue.Count > 0) { Log.Info("从队列取"); prefabPool = m_PrefabPoolQueue.Dequeue(); prefabPool.PrefabPoolId = id; gameObjectPoolEntity.Pool.AddPrefabPool(prefabPool); prefabPool.prefab = prefab; prefabPool.prefabGO = prefab.gameObject; prefabPool.AddPrefabToDic(prefab.name, prefab); } else { prefabPool = new PrefabPool(prefab, id); gameObjectPoolEntity.Pool.CreatePrefabPool(prefabPool, resEntity); } prefabPool.OnPrefabPoolClear = (PrefabPool pool) => { //预设池加入队列 pool.PrefabPoolId = 0; gameObjectPoolEntity.Pool.RemovePrefabPool(pool); m_PrefabPoolQueue.Enqueue(pool); }; //这些属性从表格读取 prefabPool.cullDespawned = cullDespawned; prefabPool.cullAbove = cullAbove; prefabPool.cullDelay = cullDelay; prefabPool.cullMaxPerPass = cullMaxPerPass; } bool isNewInstance = false; Transform trans = gameObjectPoolEntity.Pool.Spawn(prefab, ref isNewInstance, resEntity); int instanceId = trans.gameObject.GetInstanceID(); m_InstanceIdPoolDic[instanceId] = poolId; return (trans, isNewInstance); //} } #endregion #region Despawn /// /// 对象回池 /// /// /// public void Despawn(byte poolId, Transform instance) { if (m_SpawnPoolDic.TryGetValue(poolId, out GameObjectPoolEntity entity)) { instance.SetParent(entity.Pool.transform); entity.Pool.Despawn(instance); } } /// /// 对象回池 /// /// public void Despawn(Transform instance) { int instanceId = instance.gameObject.GetInstanceID(); if (m_InstanceIdPoolDic.TryGetValue(instanceId, out byte poolId)) { m_InstanceIdPoolDic.Remove(instanceId); Despawn(poolId, instance); } } #endregion public void Destroy() { m_SpawnPoolDic?.Clear(); } } }