美文网首页
对象池技术

对象池技术

作者: 胤醚貔貅 | 来源:发表于2017-05-18 18:46 被阅读60次

Unity 对象池技术

为什么使用对象池?

在我们开发中,往往会遇见需要不断创建和销毁同一物体的情况。(如飞机大战,许多FPS游戏,三消类游戏等),这时我们系统不断的实例化资源和销毁资源对于内存以及性能的消耗是非常大的。对于这种我们可以使用对象池技术进行优化。效果十分明显。

对象池及时的原理:

适用范围:有大量的物体需要被不断的创建和销毁的时候。

关键点:

从对象池中放入对象。

从对象池中取出对象。

使用何种数据类型来对这些对象进行储存。

关键思想:

相比于Instantiate和Destroy,不断的实例化和销毁,对象池只是对它们实例化出的对象进行激活和失活的处理。

我们配合Unity来进行实际的演示。

以最简单的打砖块案例进行讲解,具体自己的项目自己进行分析和解决。

首先通过脚本动态创建出一堵墙。

Paste_Image.png

通过射线实现子弹的发射。点击时创建预设并拿到预设的刚体组件添加力。


如果我们不进行销毁,那子弹将会一直存在于我们的场景,对我们的内存造成巨大的负担,这里我们可以是Destroy方法进行延时销毁。

但问题又来了这只是一个小小的Demo,如果我们的游戏场景里的资源有许多许多加上特效加上各种开销,我们如果再这样不断的向内存申请空间创建对象在销毁对象,这样使性能十分的低效。

通过上述例子我们可以发现,子弹是不断的被创建又不断的被销毁。符合我们的对象池技术需求。

使用对象池。

首先在场景中的游戏控制器上添加ObjectPool脚本。

ObjectPool的核心思想为如果存入对象池中,如何取出,用什么数据类型存储

我们来对ObjectPool类进行实现

如何存储

由于对象池是管理整个游戏的,并且我们的对象池只需要一个,我们需要单例模式。

我们的对象池中可能不仅仅只有Bullet子弹这一种需要管理的资源,还有许多可能需要储存的资源,我们需要使用一个数组来进行存储,但是每种资源的类型都是不同的,所以这里我们可以使用ArrayList这种数据类型来进行存储。

我们的每一种资源则对应了储存这种资源的ArrayList,所以我们可以使用键值对来进行一一对应。

思路逻辑清晰以后,我们来开始进行实现。

构建ObjectPool类。使用单例模式并添加键值对来进行储存。(这里为了简单方便讲解使用string类型作为key)

Paste_Image.png

接着我们需要对资源进行储存。(将数据存入对象池)

这里构建一个Return方法来实现储存。

首先跟着游戏对象的名字作为key

如果pool键值对中有key的值,我们将它Add在key所对应的ArrayList中。

如果pool键值对中没有key的值,我们则为这个key开辟一个ArrayList用于存储它。

并将它的Active设置为false(场景中的表现为消失,效果同Destroy但是这个资源并没有被回收)

Paste_Image.png

我们定义一个Get方法用于往对象池里取出对象。

Get类的设计思路,由于我们实例化出来的预设都是作为(Clone)来存在,所以我们将键值对的Key定义为一个原预设名加上(Clone)的形式。

声明一个Object的对象o。

判断键值对中是否有这个键,如果有,再判断这个键所对应的值是否为空。如果不为空,则将这个对象从ArrayList中取出后并在Arrarlist中删除。

作为我们需要使用的对象,由于之前储存的时候,我们将对象失活,现在我们需要将它激活,并设置它相应的position,和rotation。

如果不是上述的情况,说明我们的对象现在还没有被实例化出来(或者是需要从对象池中取出的数量小于场景中需要使用的数量时),我们就需要实例化对象。这里使用Resources.Load方法。

Paste_Image.png

Paste_Image.png

对象池构建完毕以后,我们将对象池进行应用。

直接使用对象池的对象来获取对象,而不是直接实例化出来对象。

Paste_Image.png

在Destroy方法处,进行相应的修改。

首先我们要淘汰之前的Destroy方法。

Paste_Image.png

并声明一个初始化的方法,用于开启协程。(每隔两秒将实例化出来的对象失活并储存入对象池中)


接着我们就不能再Srart中去调用这个方法,因为Start只能在对象实例化之后运行一次,而我们进行的是不断的失活和激活的动作。对象从对象池中使用是,不断的失活和激活过程(拿出来使用是激活,使用过后放回去失活),所以我们需要把这个失活的操作放在OnEnable()回调方法中,让它延时2f进行失活而不能放在Start中。


对象池完成。

这样对象池就会根据我们子弹的生命周期(这里是2f),初始化和复用相应数量的游戏对象,使用时就激活,不使用时就失活。不会再进行不断的初始化和销毁。

相关文章

  • 对象池技术

    Unity 对象池技术 为什么使用对象池? 在我们开发中,往往会遇见需要不断创建和销毁同一物体的情况。(如飞机大战...

  • commons-pool2 池化技术探究

    一、前言 我们经常会接触各种池化的技术或者概念,包括对象池、连接池、线程池等,池化技术最大的好处就是实现对象的重复...

  • Netty对象池实现分析

    什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的...

  • 池技术使用-commons-pool2

    池技术 日常搬砖过程中对池技术的接触很多,最具代表的是连接池。连接池也是一种池技术,本质上都是对象池。common...

  • java 对象池技术

    中断了一段时间,再次开始技术之旅;心里有个小目标,先把对象池技术梳理清楚。 1、为什么用对象池 在 java 中,...

  • Unity 对象池技术

    Unity 对象池技术 为什么使用对象池? 在我们开发中,往往会遇见需要不断创建和销毁同一物体的情况。(如飞机大战...

  • [缓存]对象池技术

    1.思想 核心就是将需要频繁创建和销毁而且开销很大的对象做缓存,用到的时候去对象池中取,避免频繁创建,产生内存碎片...

  • 对象池化技术

    科普一下对象池化技术,来抄代码的直接略过就行 ; - )什么是对象池化?对象被创建后,使用完毕不是立即销毁回收对象...

  • Apache Object Pool源码解析

    解读Thrift服务获取代码时发现有使用对象池技术, 顺便研究一下对象池技术 基础知识 wait/notify w...

  • 数据库连接池、线程池等管理的关键点,你知道吗?

    在Java应用开发中经常会用到连接池、线程池等池化技术。池化(pool)技术的本质是通过复用对象、连接等资源,减少...

网友评论

      本文标题:对象池技术

      本文链接:https://www.haomeiwen.com/subject/aptexxtx.html