177 lines
5.7 KiB
C#
177 lines
5.7 KiB
C#
using System;
|
|
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>
|
|
{
|
|
/// <summary>鱼 prefab 获取委托:由热更侧 FishResourcesData 初始化时注入,框架层不反向依赖热更类型</summary>
|
|
public static Func<int, GameObject> GetFishPrefab;
|
|
|
|
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 = GetFishPrefab != null ? GetFishPrefab(id) : null;
|
|
if (temp == null)
|
|
{
|
|
Debug.LogError($"[Pool] 找不到鱼 prefab, fishNumber={id}");
|
|
return null;
|
|
}
|
|
obj = GameObject.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
|
|
{
|
|
var prefab = GetFishPrefab != null ? GetFishPrefab(id) : null;
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogError($"[Pool] 找不到鱼 prefab, fishNumber={id}");
|
|
return null;
|
|
}
|
|
// ⭐ 无位置实例化(保留预制体自带的位置/深度),再只覆盖 x/y,z 用预制体自带的
|
|
obj = GameObject.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;
|
|
//}
|
|
/// <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;
|
|
}
|
|
}
|
|
}
|