首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > Unity3D研究院之初探PoolManager插件(七十四)
2014
07-18

Unity3D研究院之初探PoolManager插件(七十四)

前几天我在博客里面分享了为什么Unity实例化很慢的原因,并且也分享了一个缓存池的工具。有朋友给我留言说PoolManager插件非常好用,我抽空研究了一下确实很好用。PoolManager目前的最新版本是5.5.2 我有幸在网络上找到了破解版本,文章最后我会放出来不过还是希望大家支持正版嘿嘿。

PoolManager5 介绍: https://www.assetstore.unity3d.com/en/#!/content/1010

为什么Unity实例化对象慢的原因请看我之前的文章 http://www.xuanyusong.com/archives/2925

缓存池我们主要关注的几个事情 1.怎么把游戏对象保存进缓存池 2.怎么把游戏对象从缓存池里面去出来 3.如何智能删除缓存池。很期待,因为PoolManager都满足了这几个需求。如下图所示,创建一个空的GameObjcet 接着把Spawn Pool脚本绑上去。

PoolName:缓存池的唯一名称。

MatchPoolScale:勾选后实例化的游戏对象的缩放比例将全是1,不勾选择用Prefab默认的。

MachPool Layer:勾选后实例化的游戏对象的Layer将用Prefab默认的。

Don’t Reparent:勾选后实例化的对象将没有父节点,通通在最上层,建议不要勾选。

Don’t Destroy On Load:这个就不用我解释了吧?切换场景不施放。

Pre-Prefab Pool Options :缓存池列表,意思就是缓存列表里面可以放各种类型的Prefab。右边有个 “+”按钮点击就添加每个类型的Prefab了,后面会介绍脚本怎么动态添加。

prefab:可以直接把工程里的Prefab直接拖进来。

preloadAmount:缓存池这个Prefab的最大保存数量。

preloadTime:如果都选表示缓存池所有的gameobject可以“异步”加载。

preloadFrames:每几帧加载一个。

preloadDelay:延迟多就开始加载。

limitInstance:是否开始实例的限制功能。

limit Amount:限制缓存池里最大的Prefab的数量,它和上面的preloadAmount是有冲突的,如果同时开启则以limitAmout为准。

limitFIFO:如果我们限制了缓存池里面只能有10个Prefab,如果不勾选它,那么你拿第11个的时候就会返回null。如果勾选它在取第11个的时候他会返回给你前10个里最不常用的那个。

cullDespawend:是否开启缓存池智能自动清理模式。

cull Above:缓存池自动清理,但是始终保留几个对象不清理。

cull Delay:每过多久执行一遍自动清理,单位是秒。

cullMaxPerPass:每次自动清理几个游戏对象。

补充一下,这里我们说的自动清理,就是当池子里面的对象setActive(false)也就是目前不用的时候,poolManager会根据上述参数自动清理这些对象,清理也就是Destroy()掉。
Unity3D研究院之初探PoolManager插件(七十四) - 雨松MOMO程序研究院 - 1

上面我详细的把PoolManager核心的参数统统介绍了一遍。上面的做法我们是在游戏运行前提前去初始化已知的游戏对象,可是实际游戏中往往我们需要动态的去载入一些无法提前预知的游戏对象,所以初始化内存池的操作我建议还是在脚本里面来完成。

如下图所示,我们在Hierarchy视图里面就创建一个PoolManager对象,上面挂上SpawnPool脚本,标记它为Don’tDestroyOnLoad状态。


Unity3D研究院之初探PoolManager插件(七十四) - 雨松MOMO程序研究院 - 2 下面我们看看怎么通过脚本来动态的给内存池里面加东西。

   spawnPool.Despawn() 可以单独从池子里面清空某一个Prefab。

    spawnPool.Insert() 还可以插入在池子里面某个序列上。

Unity3D研究院之初探PoolManager插件(七十四) - 雨松MOMO程序研究院 - 3

 

最后是完整的游戏代码,并且包括PoolManager5的插件。 大家来下载吧。

http://pan.baidu.com/s/1gdEG7dx

雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!

--

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。

  1. 这部分源码我仔细看了下,感觉preloadFrames这个参数就不是 每几帧加载一个的意思啊,下面这部分代码,明明是每帧加载一个,而且是分成几次循环来完成的,完全不知道有什么意义,是我理解有问题么,希望momo大大不吝赐教! private IEnumerator PreloadOverTime() { yield return new WaitForSeconds(this.preloadDelay); Transform inst; // subtract anything spawned by other scripts, just in case int amount = this.preloadAmount – this.totalCount; if (amount <= 0) yield break; // Doesn’t work for Windows8… // This does the division and sets the remainder as an out value. //int numPerFrame = System.Math.DivRem(amount, this.preloadFrames, out remainder); int remainder = amount % this.preloadFrames; int numPerFrame = amount / this.preloadFrames; // Reduce debug spam: Turn off this.logMessages then set it back when done. this.forceLoggingSilent = true; int numThisFrame; for (int i = 0; i < this.preloadFrames; i++) { // Add the remainder to the *last* frame numThisFrame = numPerFrame; if (i == this.preloadFrames – 1) { numThisFrame += remainder; } for (int n = 0; n < numThisFrame; n++) { // Preload… // This will parent, position and orient the instance // under the SpawnPool.group inst = this.SpawnNew(); if (inst != null) this.DespawnInstance(inst, false); yield return null; } // Safety check in case something else is making instances. // Quit early if done early if (this.totalCount > this.preloadAmount) break; } // Restore the previous setting this.forceLoggingSilent = false; }

  2. momo你好,我想做到的是Spawn多个包含动画的Object,每一个在动画播放完毕之后被销毁。然后我在动画结束后将其设为Inactive,但是好像不能自动帮我清理啊。于是我只好在动画播放完毕后手动调用Despawn函数,可是这不就和Destroy没区别嘛。该怎么解决呢?

  3. momo,用完的对象有没有试过用Despawn放回到池中?我总是感觉这重新放回到池中的对象再拿出来还是和全新的不一样。你再实际使用中有没有用过Despawn放回池的操作?

  4. 通过Recource.Load加载的spine 无法被真正的释放掉,即使跨场景也还是在内存里面而AssetBundle加载的也有点问题松神遇到过没?

  5. 最近在研究这个插件, 出了个问题:重用之前Item的时候, 在Scrollview 中拖拽的时候 scrollview 的clip功能对Item中的icon失效, 也就是说超过scrollview范围后 还是能看到item的icon… 请问楼主有遇到这样的情况没, 不知道如何下手解决这个bug