转载两个写的非常好的关于Unity对象池的文章

我是写不出来,但是我看了他们的我就能写出来了。
相信你看了也肯定知道你自己的框架怎么搭建出来。
Unity3D内存管理——对象池(Object Pool)
Object Pooling in Unity
Unity3d中对象池(ObjectPool)的实现

我觉得有些对象可以自动回收,有些常驻的需要手动。

下面是我看了他们的文章写出来的对象池,在我自购的框架中。

using System.Collections.Generic;
using System;
using UnityEngine;

namespace Pool
{
    /// <summary>
    /// 属于场景
    /// 不同的场景共享不同的对象集合
    /// 我的对象池使用标签来进行管理,注意要让标签和对象资源的名称相同
    /// </summary>
    public class PoolManager:MonoBehaviour
    {
        //共享单例
        public static PoolManager SharedInstance;
        //检测自动释放时间
        private int AutoReleaseTime = 10;
        private List<ObjectPool> m_PoolList = new List<ObjectPool>();
        private List<IPoolableObject> m_HideObjs = new List<IPoolableObject>();

        private void Awake()
        {
            SharedInstance = this;
        }
        private void Start()
        {
            //对象池初始化
            for (int i = 0; i < m_PoolList.Count; i++)
            {
                for (int j = 0; j < m_PoolList[i].InitialBufferSize; j++)
                {
                    IPoolableObject o = New(m_PoolList[i].ResName);
                    RecycleObject(o);
                }
            }
            //开启自动回收
            InvokeRepeating("AutoRelease", AutoReleaseTime, AutoReleaseTime);
        }
        /// <summary>
        /// 处理对象资源的隐藏时间
        /// </summary>
        private void Update()
        {
            for (int i = 0; i < m_HideObjs.Count; i++)
            {
                m_HideObjs[i].HideTime += Time.deltaTime;
            }
        }
        /// <summary>
        /// New新物体
        /// </summary>
        /// <param name="tag">物体的Tag=物体资源名称</param>
        /// <returns></returns>
        public IPoolableObject New(string tag)
        {
            //如果池子里面存在需要的对象
            for (int i = 0; i < m_PoolList.Count; i++)
            {
                if(m_PoolList[i].ResName==tag)
                {
                    if(m_PoolList[i].NextAvailableIndex<m_PoolList.Count)
                    {
                        IPoolableObject o = m_PoolList[i].PoolObjects[m_PoolList[i].NextAvailableIndex++];
                        return o;
                    }
                    else
                    {
                        //新增物体
                        if (m_PoolList[i].ShouldExpand)
                        {
                            for (int j = 0; j < m_PoolList[i].ExpandSize; j++)
                            {
                                GameObject obj = (GameObject)Instantiate(GameManager.Instance.LoadObject<GameObject>(m_PoolList[i].ResName));
                                obj.SetActive(false);
                                IPoolableObject o = obj.GetComponent<IPoolableObject>();
                                m_PoolList[i].PoolObjects.Add(o);
                            }
                            //补全占满
                            m_PoolList[i].NextAvailableIndex++;
                            return m_PoolList[i].PoolObjects[m_PoolList[i].NextAvailableIndex-1];
                        }
                        else
                        {
                            Debug.LogError(tag + "对象池已经占满,而且不允许拓展!");
                            return null;
                        }
                    }
                }
            }
            Debug.LogError(tag + "的物体在该场景中不由对象池进行管理!");
            return null;
        }
        /// <summary>
        /// 回收一个物体
        /// </summary>
        /// <param name="o">物体</param>
        public void RecycleObject(IPoolableObject o)
        {
            //更新活动指针
            for (int i = 0; i < m_PoolList.Count; i++)
            {
                if(m_PoolList[i].ResName==o.tag)
                {
                    m_PoolList[i].PoolObjects.Remove(o);
                    m_PoolList[i].PoolObjects.Add(o);
                }
            }
            o.gameObject.SetActive(false);
            m_HideObjs.Add(o);
        }
        /// <summary>
        /// 卸载释放一个对象(从对象池中)
        /// </summary>
        /// <param name="o">对象</param>
        private void ReleaseObject(IPoolableObject o)
        {
            //总池删除
            for (int i = 0; i < m_PoolList.Count; i++)
            {
                if(m_PoolList[i].ResName==o.tag)
                {
                    m_PoolList[i].PoolObjects.Remove(o);
                }
            }
            //隐藏池删除
            if (m_HideObjs.Contains(o))
                m_HideObjs.Remove(o);
            Destroy(o.gameObject);
        }
        /// <summary>
        /// 全部卸载
        /// </summary>
        public void ReleaseAll()
        {
            //取消回调
            CancelInvoke();
            //内存释放
            m_HideObjs.Clear();
            m_PoolList.Clear();
            //单例释放
            SharedInstance = null;
        }
        /// <summary>
        /// 自动回收
        /// </summary>
        private void AutoRelease()
        {
            for (int i = 0; i < m_PoolList.Count; i++)
            {
                for (int j = 0; j < m_PoolList[i].PoolObjects.Count; j++)
                {
                    if(m_PoolList[i].IsAutoRecycle)
                    {
                        if(m_PoolList[i].PoolObjects[j].HideTime>m_PoolList[i].MaxHideTime)
                        {
                            ReleaseObject(m_PoolList[i].PoolObjects[j]);
                        }
                    }
                }
            }
        }
    }
}


using UnityEngine;
using System.Collections.Generic;
namespace Pool
{
    /// <summary>
    /// 需要经由对象池加载的Prefab
    /// </summary>
    [System.Serializable]
    public class ObjectPool
    {
        //初始化最大数量
        public int InitialBufferSize;
        //预制体资源的名称,由AB包进行一个加载
        public string ResName;
        //是否允许扩展
        public bool ShouldExpand;
        //每次扩展个数
        public int ExpandSize;
        //下一个可用GO的索引
        public int NextAvailableIndex = 0;
        //池内资源是否自动释放
        public bool IsAutoRecycle = true;
        //这种资源的最大隐藏时间
        public int MaxHideTime;
        [System.NonSerialized]
        //对象集合
        public List<IPoolableObject> PoolObjects;
    }

}

using UnityEngine;

namespace Pool
{
    public abstract class IPoolableObject : MonoBehaviour
    {
        //隐藏时间超过就自动释放
        public float HideTime;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JustEasyCode

谢谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值