Unity 对象池

概念

我们先讲讲对象池是什么,有什么用。在游戏的制作过程中,我们可能会碰到这样的情况,就像现在最火的吃鸡游戏一样,我们有一把枪,开枪的时候射出子弹。每个子弹即一个对象,正常情况,我们的处理方式可能会是,每开一枪,就GameObject.Instantiate()一个新的子弹,当子弹到达极限距离的时候再GameObject.Destroy()销毁它。假设有射出1000发子弹,我们就会执行1000次这样的操作,然而在Unity中Instantiate和Destroy操作,不仅影响性能还容易产生内存碎片,总之就是要尽量少做这种操作。这个时候就有对象池这个概念。

所谓对象池,就是针对需要经常生成消失的对象。我们在对象需要消失的时候不Destroy而是SetActive(false),然后放入池子中(Queue),当需要再次显示一个新的对象的时候,先去池子中看有没有隐藏的对象,有就取出SetActive(true),若池子里没有可用的则再Instantiate。

还是上面的例子,假设我们玩家能看见的子弹只有10发,那么在连续开枪1000次的时候,我们生成第一发子弹的时候,此时对象池为空,我们Instantiate一个子弹,第二到第十发子弹的时候同理,再Instantiate九个子弹,第十一发的时候,前十发子弹还是处于显示状态,池子中依旧为空,我们继续Instantiate一个子弹,当这个子弹射出的时候,我们的第一发子弹就应该无法看见了,我们即可SetActive(false),然后放入对象池中。当第12发子弹的时候,我们这个时候对象池里就有一个可用对象,即第一发子弹,我们取出并显示它,然后将它的起始坐标更新到枪口。第13发子弹之后就如此循环。这样,我们在1000发子弹的时候只需要执行11次Instantiate和Destroy操作,起到优化作用。

实现

注:实现的方式有很多,下面只是个人的一种方式,大家可以针对自己的需求任意修改。

了解了上面的概念之后,实现起来就很方便了。首先我们先生成一个对象池的class,里面的内容就很简单,首先有一个Queue用来存放池子中的对象,然后实现两个方法,一个取对象,一个销毁对象,取对象的时候,若池子中有可用对象则取出一个,若没有则Instantiate一个。销毁对象即将对象SetActive(false)并且放入池子中。代码如下

public class BaseGameObjectPool {

    /// <summary>
    /// 队列,存放对象池中没有用到的对象,即可分配对象
    /// </summary>
    protected Queue m_queue;
    /// <summary>
    /// 对象池中存放最大数量
    /// </summary>
    protected int m_maxCount;
    /// <summary>
    /// 对象预设
    /// </summary>
    protected GameObject m_prefab;
    /// <summary>
    /// 该对象池的transform
    /// </summary>
    protected Transform m_trans;
    /// <summary>
    /// 每个对象池的名称,当唯一id
    /// </summary>
    protected string m_poolName;
    /// <summary>
    /// 默认最大容量
    /// </summary&g
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值