【Unity UISystem】ObjectPool

在Unity游戏开发中,ObjectPool是一种用于优化游戏性能的缓存池,它通过循环利用对象减少频繁创建和销毁带来的内存碎片,从而避免游戏卡顿。ObjectPool采用后进先出的Stack结构,支持在获取和释放对象时执行回调函数。

【Unity UISystem】ObjectPool

是什么

通过对Unity的UI源码(源码地址:https://bitbucket.org/Unity-Technologies/ui/src/2019.1/)解析我们发现了一个对游戏性能优化相关的一个Object缓存池ObjectPool.cs
在这里插入图片描述

为什么

在游戏中,我们需要创建和销毁3D模型,粒子特效,List,Array,包括战斗中由于频繁释放技能创建出来的子弹等物体,它们在频繁的销毁创建过程中会产生很多的碎片在内存中,如果没有一个统一的管理器来循环利用很容易造成游戏卡顿。因此ObjectPool就是用来对游戏中的Object对象进行对象池管理用的。

怎么做

下面我们来查看源码,看下其实现原理。

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

namespace UnityEngine.UI
{
    internal class ObjectPool<T> where T : new()
    {
        private readonly Stack<T> m_Stack = new Stack<T>();
        private readonly UnityAction<T> m_ActionOnGet;
        private readonly UnityAction<T> m_ActionOnRelease;

        public int countAll { get; private set; }
        public int countActive { get { return countAll - countInactive; } }
        public int countInactive { get { return m_Stack.Count; } }

        public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease)
        {
            m_ActionOnGet = actionOnGet;
            m_ActionOnRelease = actionOnRelease;
        }

        public T Get()
        {
            T element;
            if (m_Stack.Count == 0)
            {
                element = new T();
                countAll++;
            }
            else
            {
                element = m_Stack.Pop();
            }
            if (m_ActionOnGet != null)
                m_ActionOnGet(element);
            return element;
        }

        public void Release(T element)
        {
            if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element))
                Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
            if (m_ActionOnRelease != null)
                m_ActionOnRelease(element);
            m_Stack.Push(element);
        }
    }
}

ObjectPool使用了一个Stack堆(last-in-first-out (LIFO))后进先出的结构,当我们需要新建(Get)一个新的Object的时候先从Stack的堆顶取出第一个,当使用结束的时候将其释放掉(Release),也就是将其重新放回Stack堆里面。原理其实很简单,当然里面增加了放进和放出时候的Action,可以用来传入回调函数,分别在取出和释放的时候调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值