前几天我在博客里面分享了为什么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()掉。
上面我详细的把PoolManager核心的参数统统介绍了一遍。上面的做法我们是在游戏运行前提前去初始化已知的游戏对象,可是实际游戏中往往我们需要动态的去载入一些无法提前预知的游戏对象,所以初始化内存池的操作我建议还是在脚本里面来完成。
如下图所示,我们在Hierarchy视图里面就创建一个PoolManager对象,上面挂上SpawnPool脚本,标记它为Don’tDestroyOnLoad状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
using
UnityEngine
;
using
System
.
Collections
;
using
PathologicalGames
;
public
class
NewBehaviourScript
:
MonoBehaviour
{
SpawnPool
spawnPool
;
PrefabPool
refabPool
;
void
Start
(
)
{
spawnPool
=
PoolManager
.
Pools
[
"Shapes"
]
;
refabPool
=
new
PrefabPool
(
Resources
.
Load
<
Transform
>
(
"momo"
)
)
;
}
void
OnGUI
(
)
{
if
(
GUILayout
.
Button
(
"初始化内存池"
)
)
{
if
(
!
spawnPool
.
_perPrefabPoolOptions
.
Contains
(
refabPool
)
)
{
refabPool
=
new
PrefabPool
(
Resources
.
Load
<
Transform
>
(
"momo"
)
)
;
//默认初始化两个Prefab
refabPool
.
preloadAmount
=
2
;
//开启限制
refabPool
.
limitInstances
=
true
;
//关闭无限取Prefab
refabPool
.
limitFIFO
=
false
;
//限制池子里最大的Prefab数量
refabPool
.
limitAmount
=
5
;
//开启自动清理池子
refabPool
.
cullDespawned
=
true
;
//最终保留
refabPool
.
cullAbove
=
10
;
//多久清理一次
refabPool
.
cullDelay
=
5
;
//每次清理几个
refabPool
.
cullMaxPerPass
=
5
;
//初始化内存池
spawnPool
.
_perPrefabPoolOptions
.
Add
(
refabPool
)
;
spawnPool
.
CreatePrefabPool
(
spawnPool
.
_perPrefabPoolOptions
[
spawnPool
.
Count
]
)
;
}
}
if
(
GUILayout
.
Button
(
"从内存池里面取对象"
)
)
{
///从内存池里面取一个GameObjcet
Transform
momo
=
spawnPool
.
Spawn
(
"momo"
)
;
}
if
(
GUILayout
.
Button
(
"清空内存池"
)
)
{
//清空池子
spawnPool
.
DespawnAll
(
)
;
}
}
}
|
spawnPool.Despawn() 可以单独从池子里面清空某一个Prefab。
spawnPool.Insert() 还可以插入在池子里面某个序列上。
最后是完整的游戏代码,并且包括PoolManager5的插件。 大家来下载吧。
http://pan.baidu.com/s/1gdEG7dx