Unity 通用 对象池管理

	一般情况下我们使用对象池是物体的创建和管理。但在很多情况下需要批量创建的物体需要做一些逻辑处理,这样我们需要记录对象池对应的数据状态。
	所以我们就直接把对象作为管理对象,这样我们可以在对象里面做一些逻辑处理还能便于物体管理。

ItemClassBase类

作为对象管理类,那么我们必须要一个同一个父类作为管理的类别。在父类里面包含一些基础的函数方法。
便于在实例化的时候统一规范。
public class ItemClassBase
{
    public Transform transform;

    public ItemClassBase()
    {
    }

    public virtual void Init(Transform trans)
    {
        transform = trans;
    }

    public virtual void Show(Transform parentTransform)
    {
        transform.SetParent(parentTransform);
        transform.localScale = Vector3.one;
        transform.transform.localPosition = Vector3.zero;
        transform.gameObject.SetActive(true);
    }

    public virtual void Hide()
    {
        transform.gameObject.SetActive(false);
    }

    public virtual void SetSiblingIndex(int index)
    {
        transform.SetSiblingIndex(index);
    }
}

对象管理类ObjectPoolsMgr

这就是普通的对象管理类,把对象想物体创建一样管理。

public class ObjectPoolsMgr 
{
    public static ObjectPoolsMgr Instance = new Lazy<ObjectPoolsMgr>(()=> new ObjectPoolsMgr()).Value;
    GameObject buildRoot;
    GameObject BuildRoot
    {
        get
        {
            if (buildRoot == null)
            {
                buildRoot = new GameObject();
                buildRoot.name = "BuildRoot";
            }
            return buildRoot;
        }
    }
	Dictionary<string, Transform> dicPoolTrans = new Dictionary<string, Transform>();
    Dictionary<string, List<ItemClassBase>> m_DicPool = new Dictionary<string, List<ItemClassBase>>();
    Dictionary<string, List<ItemClassBase>> m_DicUse = new Dictionary<string, List<ItemClassBase>>();   

    //创建对象的对象池  默认1个
    public T GetItemObject<T>(Transform trans, int Count = 1) where T : ItemClassBase
    {
        T m_T = null;
        string name = typeof(T).Name;
        if (dicPoolTrans.ContainsKey(name))
        {
            trans = dicPoolTrans[name];
        }
        else
        {
            dicPoolTrans.Add(name, trans);
        }
        if (!m_DicPool.ContainsKey(name) || m_DicPool[name].Count == 0)
        {
            for (int i = 0; i < Count; i++)
            {
                Transform tran = GameObject.Instantiate(trans, BuildRoot.transform);
                ItemClassBase m_base = Activator.CreateInstance(typeof(T)) as ItemClassBase;
                m_base.Init(tran);
                AddItem(name, m_base);
            }
        }
        m_T = GetItem(name) as T;
        return m_T;
    }   

    //归还
    public void ReturnItem<T>(T m_this = null, bool isAll = true) where T : ItemClassBase
    {
        string name = typeof(T).Name;
        if (m_this == null)
        {
            if (m_DicUse.ContainsKey(name))
            {
                for (int i = 0; i < m_DicUse[name].Count; i++)
                {
                    m_DicUse[name][i].transform.SetParent(BuildRoot.transform);
                    m_DicUse[name][i].Hide();
                    AddItem(name, m_DicUse[name][i]);
                }
                m_DicUse.Remove(name);
            }
        }
        else
        {
            m_this.transform.SetParent(BuildRoot.transform);
            m_this.Hide();
            m_this.transform.localPosition = Vector3.zero;
            m_DicUse[name].Remove(m_this);
            AddItem(name, m_this);
        }
    }

    ItemClassBase GetItem(string itemName)
    {
        ItemClassBase m_item = m_DicPool[itemName][0];

        if (!m_DicUse.ContainsKey(itemName))
        {
            m_DicUse.Add(itemName, new List<ItemClassBase>());
        }
        m_DicUse[itemName].Add(m_item);
        m_DicPool[itemName].Remove(m_item);
        return m_item;
    }   

    void AddItem(string name, ItemClassBase item)
    {
        if (!m_DicPool.ContainsKey(name))
        {
            m_DicPool.Add(name, new List<ItemClassBase>());
        }
        if (!m_DicPool[name].Contains(item))
        {
            m_DicPool[name].Add(item);
        }       
    }
}

举例

public class A: ItemClassBase
{
    public override void Init(Transform trans)
    {       
        base.Init(trans);
        transform = trans;
    }
}
void Start()
    {      
        GameObject _time = new GameObject();
        GameObject _timeParent = new GameObject();
        A _a= ObjectPoolsMgr.Instance.GetItemObject<A>(_time.transform);
        _a.Show(_timeParent.transform);       
    }
    
void OnDesable()
    {
        ObjectPoolsMgr.Instance.ReturnItem<A>();//要回收具体某个对象的话写入就行
    }
好的,这里给出一个比较完整的Unity对象池管理脚本示例: ```csharp using System.Collections; using System.Collections.Generic; using UnityEngine; public class ObjectPool : MonoBehaviour { [SerializeField] private GameObject prefab; // 预制体 [SerializeField] private int initCount; // 初始数量 [SerializeField] private int maxCount; // 最大数量 private List<GameObject> pool; // 对象池 private Queue<int> queue; // 空闲索引队列 private void Awake() { pool = new List<GameObject>(); queue = new Queue<int>(); // 初始化对象池 for (int i = 0; i < initCount; i++) { GameObject obj = Instantiate(prefab, transform); obj.SetActive(false); pool.Add(obj); queue.Enqueue(i); } } // 从对象池中获取一个对象 public GameObject GetObject() { if (queue.Count > 0) { // 从空闲索引队列中取出一个索引 int index = queue.Dequeue(); // 返回对应的对象 return pool[index]; } else if (pool.Count < maxCount) { // 创建新的对象 GameObject obj = Instantiate(prefab, transform); obj.SetActive(false); pool.Add(obj); // 返回新创建的对象 return obj; } else { // 对象池已满,返回null return null; } } // 将对象重新加入对象池中 public void ReleaseObject(GameObject obj) { // 将对象隐藏 obj.SetActive(false); // 将索引重新加入空闲索引队列中 int index = pool.IndexOf(obj); queue.Enqueue(index); } } ``` 这个脚本实现了一个简单的对象池,可以通过调用GetObject()方法从对象池中获取一个对象,然后通过调用ReleaseObject()方法将其重新加入对象池中。在Awake()方法中,我们初始化了对象池,将初始数量的对象创建出来,并将其索引加入空闲索引队列中。在GetObject()方法中,我们从空闲索引队列中取出一个索引,然后返回对应的对象,如果对象池已满,则创建新的对象。在ReleaseObject()方法中,我们将对象隐藏,然后将其索引重新加入空闲索引队列中,以便下次可以重复利用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值