using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; public class PoolData { public GameObject fatherObj; public List poolList; public PoolData(GameObject obj,GameObject poolParent,int id) { fatherObj = new GameObject(obj.name); fatherObj.transform.parent = poolParent.transform; poolList = new List(); PushObj(obj,id); } public void PushObj(GameObject obj,int id) { // 先实例化,再隐藏(原代码对 prefab 调 SetActive(false) 无效且语义混乱) obj = GameObject.Instantiate(obj); obj.name = id.ToString(); obj.transform.parent = fatherObj.transform; obj.SetActive(false); poolList.Add(obj); } public void PushObj(GameObject obj) { poolList.Add(obj); obj.transform.parent = fatherObj.transform; obj.SetActive(false); } public GameObject GetObj() { GameObject obj; obj = poolList[0]; poolList.RemoveAt(0); obj.SetActive(true); obj.transform.parent = null; return obj; } /// /// 清理当前池子,销毁所有对象并释放父节点 /// public void Clear() { foreach (var obj in poolList) { if (obj != null) GameObject.Destroy(obj); } poolList.Clear(); if (fatherObj != null) GameObject.Destroy(fatherObj); } } public class Pool : Singleton { public Dictionary dic = new Dictionary();//生成一个字典 private GameObject poolObj;//Scene窗口中的“pool”总收纳盒 /// 获取/创建池总父节点(初始化和 Return 共用同一个 poolObj) public GameObject EnsurePoolRoot() { if (poolObj == null) poolObj = new GameObject("pool"); return poolObj; } public GameObject Get(int id, Vector3 position, Quaternion rotation)//返回一个预制体, { GameObject obj; if (dic.ContainsKey(id) && dic[id].poolList.Count > 0)//如果字典里有这个东西,并且它的数量大于0就取出来 { obj = dic[id].GetObj(); obj.transform.position = position;//实例化时候的参数传过来 obj.transform.rotation = rotation;//同上 } else { GameObject temp = FishResourcesData.GetFishPrefab(id); //if (rotation == Quaternion.identity) //{ // rotation = temp.transform.rotation; //} obj = Object.Instantiate(temp, position, rotation) as GameObject;//没有就读取一个,不用存入字典 obj.name = id.ToString(); } return obj; } public GameObject Get(int id, Vector3 position, Quaternion rotation, Transform parent )//返回一个预制体, { GameObject obj; if (dic.ContainsKey(id) && dic[id].poolList.Count > 0)//如果字典里有这个东西,并且它的数量大于0就取出来 { obj = dic[id].GetObj(); // ⭐ 设置位置不带 z 轴:z 用预制体自带的深度,不被生成位置(如 9999,9999,0)擦掉 obj.transform.position = new Vector3(position.x, position.y, obj.transform.position.z); obj.transform.rotation = rotation;//同上 obj.transform.SetParent(parent); } else { //GameObject temp = FishResourcesData.GetFishPrefab(id); //if (rotation == Quaternion.identity) //{ // rotation = temp.transform.rotation; //} var prefab = FishResourcesData.GetFishPrefab(id); if (prefab == null) { Debug.LogError($"[Pool] 找不到鱼 prefab, fishNumber={id}"); return null; } // ⭐ 无位置实例化(保留预制体自带的位置/深度),再只覆盖 x/y,z 用预制体自带的 obj = Object.Instantiate(prefab, parent) as GameObject;//没有就读取一个,不用存入字典 obj.transform.rotation = rotation; obj.transform.position = new Vector3(position.x, position.y, obj.transform.position.z); obj.SetActive(true); obj.name = id.ToString(); } return obj; } public GameObject Return(GameObject obj)//隐藏掉 { if(obj.activeSelf) { // ⭐ 统一用 poolObj 作为池总父节点(初始化时也用 poolObj,保证 Clear 能统一销毁) if(poolObj==null) { poolObj = new GameObject("pool"); } int id =int.Parse( obj.name); if (dic.ContainsKey(id))//如果找到了这个名字 { dic[id].PushObj(obj); } else { //dic.Add(id, new PoolData(obj, poolObj) { }); GameObject.Destroy(obj); } } return obj; } //public void Clear()//切换场景时将所有缓存清除 //{ // dic.Clear(); // poolObj = null; //} /// /// 清理所有池子,销毁对象并释放资源 /// public void Clear() { // ⭐ 防重入:已经清空过直接返回 if (dic.Count == 0 && poolObj == null) return; foreach (var kv in dic.Values) { if (kv != null) kv.Clear(); } dic.Clear(); if (poolObj != null) { GameObject.Destroy(poolObj); poolObj = null; } } }