Files
5.24BuYu/Assets/Framework/Pool/Pool.cs
T
2026-07-27 16:59:22 +08:00

173 lines
5.3 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
public class PoolData
{
public GameObject fatherObj;
public List<GameObject> poolList;
public PoolData(GameObject obj,GameObject poolParent,int id)
{
fatherObj = new GameObject(obj.name);
fatherObj.transform.parent = poolParent.transform;
poolList = new List<GameObject>();
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;
}
/// <summary>
/// 清理当前池子,销毁所有对象并释放父节点
/// </summary>
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<Pool>
{
public Dictionary<int, PoolData> dic = new Dictionary<int, PoolData>();//生成一个字典
private GameObject poolObj;//Scene窗口中的“pool”总收纳盒
/// <summary>获取/创建池总父节点(初始化和 Return 共用同一个 poolObj)</summary>
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();
obj.transform.position = position;//实例化时候的参数传过来
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;
}
obj = Object.Instantiate(prefab, position, rotation,parent) as GameObject;//没有就读取一个,不用存入字典
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;
//}
/// <summary>
/// 清理所有池子,销毁对象并释放资源
/// </summary>
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;
}
}
}