根据某大佬的对象池,稍微做了些改动。
可加入父节点,并根据最小数量来克隆生成多个对象。
对象池只管生成,取出,不管销毁。
若想在使用后销毁对象,需要将对象池加入指定的节点,并在节点数量达到条件后,自行判断清除,注意要从上到下清除。
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class ObjectPooler : MonoBehaviour
{
private Dictionary<string, List<GameObject>> dic;
public static ObjectPooler Instance; //单例模式,便于访问对象池
private void Awake()
{
Instance = this;
}
private ObjectPooler()
{
dic = new Dictionary<string, List<GameObject>>();
}
public Dictionary<string, List<GameObject>> GetDic()
{
return dic;
}
//取出,标签,是否删除,最小数量
public GameObject GetObj(string prefabName,string tag,bool isDel=false,bool isActive=true,Transform prentnode=null,int minNum=1)
{
// 即将返回的游戏对象
GameObject obj = null;
// 如果对象池有对象(>0就一定有一个)
if (dic.ContainsKey(tag) && dic[tag].Count > 0)
{
//出队,从对象池中获取所需的对象
Debug.Log("拿出");
obj = dic[tag][0];
if (!isDel)
{
PutObj(tag, obj);
}
dic[tag].RemoveAt(0);
// 去除名字的 "(Clone)"
//obj.name = tag;
// 将其激活
if(isActive)
{
obj.SetActive(true);
}
else
{
obj.SetActive(false);
}
if(prentnode!=null)
{
obj.transform.SetParent(prentnode);
}
// 删除列表的第一个游戏对象(因为被拿出去了)
dic[tag].RemoveAt(0);
}
// 如果没有游戏对象
else
{
// 那么实例化生成游戏对象
obj = GameObject.Instantiate(Resources.Load<GameObject>(prefabName));
if (minNum>1)
{
for(int i = 0; i < minNum; i++)
{
// 放到对象池中
PutObj(tag, obj);
//obj.name = tag;
if (isActive)
{
obj.SetActive(true);
}
else
{
obj.SetActive(false);
}
if (prentnode != null)
{
obj.transform.SetParent(prentnode);
}
}
}
else
{
// 放到对象池中
PutObj(tag, obj);
//obj.name = tag;
if (isActive)
{
obj.SetActive(true);
}
else
{
obj.SetActive(false);
}
if (prentnode != null)
{
obj.transform.SetParent(prentnode);
}
}
}
// 返回结果
return obj;
}
// 放东西
public void PutObj(string tag, GameObject obj)
{
// 将其隐藏
obj.SetActive(false);
// 如果有列表
if (dic.ContainsKey(tag))
{
// 将游戏对象添加到列表中
dic[tag].Add(obj);
}
else
{
dic.Add(tag, new List<GameObject>() { obj });
}
}
}
使用方法:
GameObject tipnode = objectPooler.GetObj("Prefab/tips","Tips",false, true, 父节点transform);
tipnode.transform.localPosition = new Vector3(0, 60, 0);
string ids = TipArrNode.childCount.ToString();
tipnode.transform.name = "tip-"+ids;//重新命名便于观察