using System.Collections; using System.Collections.Generic; using UnityEngine; /******************************************************************************* *Create By CG *Function 对象池管理_大池子 *******************************************************************************/ namespace ZXK.Framework { public class ObjectPoolsManager : ClassSingleton { //所有对象池的父物体 private GameObject _poolsParent; //所有对象池的共同父物体在Hierarchy窗口的名字 private const string _poolsParentName = "ObjectPools"; //当前所有对象池的列表 private List _objectPoolsList = new List(); //用来表示游戏对象所属的对象池 private Dictionary _objectsDictionary = new Dictionary(); /// /// 从对象池生成游戏对象。 /// 如果对象池有,从对象池中取出来用。 /// 如果对象池没有,实例化该对象。 /// public GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation, Transform parent = null) { if (prefab == null) return null; //如果场景中没有对象池的父物体,则生成一个空物体,作为所有对象池的父物体 CreatePoolsParentIfNull(); //先通过预制体来查找它所属的小对象池,如果找到了,则返回这个小对象池。 //如果找不到,则创建一个小对象池,用来存放这种预制体。 ObjectPool objectPool = FindPoolByPrefabOrCreatePool(prefab); GameObject go = objectPool.Spawn(position, rotation, parent); _objectsDictionary.Add(go, objectPool); return go; } public void Despawn(GameObject go, float delayTime = 0) { if (go == null) return; MonoManager.Instance.StartCoroutine(DespawnCoroutine(go, delayTime)); } IEnumerator DespawnCoroutine(GameObject go, float delayTime = 0) { //等待指定秒数 if (delayTime > 0) yield return new WaitForSeconds(delayTime); if (_objectsDictionary.TryGetValue(go, out ObjectPool pool)) { _objectsDictionary.Remove(go); pool.Despawn(go); } else { //获取这个游戏对象所属的对象池 pool = FindPoolByUsedGameObject(go); if (pool != null) { pool.Despawn(go); } } } ObjectPool FindPoolByUsedGameObject(GameObject go) { if (go == null) return null; for (int i = 0; i < _objectPoolsList.Count; i++) { ObjectPool pool = _objectPoolsList[i]; for (int j = 0; j < pool._UsedGameObjectList.Count; j++) { if (pool._UsedGameObjectList[j] == go) return pool; } } return null; } //先通过预制体来查找它所属的小对象池,如果找到了,则返回这个小对象池。 //如果找不到,则创建一个小对象池,用来存放这种预制体。 private ObjectPool FindPoolByPrefabOrCreatePool(GameObject prefab) { //确保大对象池是存在的 CreatePoolsParentIfNull(); //查找并返回该预制体对数的对象池 ObjectPool objectPool = null; if (prefab != null) { for (int i = 0; i < _objectPoolsList.Count; i++) { if (_objectPoolsList[i]._Prefab == prefab) objectPool = _objectPoolsList[i]; } } if (objectPool == null) { objectPool = new GameObject($"ObjectPool_{prefab.name}").AddComponent(); objectPool._Prefab = prefab; objectPool.transform.SetParent(_poolsParent.transform); _objectPoolsList.Add(objectPool); } return objectPool; } //如果场景中没有对象池的父物体,则生成一个空物体,作为所有对象池的父物体。 private void CreatePoolsParentIfNull() { if (_poolsParent == null) { _objectPoolsList.Clear(); _objectsDictionary.Clear(); _poolsParent = new GameObject(_poolsParentName); } } } }