对象池微改版

根据某大佬的对象池,稍微做了些改动。

可加入父节点,并根据最小数量来克隆生成多个对象。

对象池只管生成,取出,不管销毁。

若想在使用后销毁对象,需要将对象池加入指定的节点,并在节点数量达到条件后,自行判断清除,注意要从上到下清除。

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;//重新命名便于观察

猜你喜欢

转载自blog.csdn.net/qq_41589481/article/details/128132588
今日推荐