Spawnpool 的使用 带实例
最近也是看到一个挺不错的插件,所以自己简单应用了一下。和大家分享下。
之前一直用的是ObjectPool,也就是对象池做东西,没想到还有怎么好的插件缓冲池,确实对实例化的东西可以提高实例化的速度和优化内存。使用起来也挺方便的。
首先就是对spwanpool 的介绍:(我用的PoolManager版本是5.5.2的)
PoolName:缓存池的唯一名称。
MatchPoolScale:勾选后实例化的游戏对象的缩放比例将全是1,不勾选择用Prefab默认的。
MachPool Layer:勾选后实例化的游戏对象的Layer将用Prefab默认的。
Don’t Reparent:勾选后实例化的对象将没有父节点,通通在最上层,建议不要勾选。
Don’t Destroy On Load:这个就不用我解释了吧?切换场景不释放。
Log Messages 是否打印日志信息
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:每次自动清理几个游戏对象。
缓冲池的几个重要脚本:
1、SpawnPool脚本
脚本用在布局场景时,就把游戏运行用时频繁到的物体存放到此脚本创建的缓存池中在需要时使用就好,下面还有一个是用在场景布局时不准备用到的物体,而是在用到时使用代码动态的创建一个缓存池来使用。
limitInstance是否开启(打钩)的区别:
不开启情况:假如此时preloadAmount为1,如果用户想要每隔5秒去Spawn一个缓冲池中的对象,那么当加载第二个prefab对象的时候,缓冲池会再创建一个此对象,如果程序再Spawn,那么还会在产生一个这样的对象,就这样一直产生下去,Spawn几次就产生几个对象!
(粒子系统:循环时:Spawn几次,就会产生几个对象,不循环时(循环结束状态为false):会再产生一个对象,如果此时的Spawn速度特别快,并且检测不到前面的对象状态为false,那么可能会产生多个对象,直到检测到前面的几个对象有false状态,那么产生对象到此为止,程序在此几个对象之间来回Spawn!)
开启情况:
此时Limit Amount为1
limitFIFO勾选:那么程序永远使用的是预加载对象,而不会再产生其他对象!当加载第二次的时候,即使第一个对象处于true状态,也使用它,即操作第一个对象!(粒子系统为循环或者不循环时,效果和这一样)
limitFIFO不勾选:那么程序永远使用的是预加载对象,而不会再产生其他对象!当加载第二次的时候,那么必须等第一个对象变为false状态,才能使用它!如果过了5s,第一个对象还没变为false状态,那么程序会报错!(粒子系统为循环:会循环下去,只有一个预加载对象,不报错,不循环时:等上一个变为false才能进行第二次,只有一个预加载对象,不报错!)
如果limit Amount数量大于1,为10的话
limitFIFO勾选:永远只有10个对象产生,当加载第11个对象时,如果前十个对象没有一个active为false状态,那么程序会选择不常用的那个,从而避免报错!
limitFIFO不勾选:永远只有10个对象产生,但是当加载第11个对象时,如果前十个对象没有一个active为false状态,那么程序会报错!
获取缓冲池的方式:
SpawnPool pool = PoolManager.Pools[poolName];
SpawnPool pool = this.GetComponent<SpawnPool>();
2、PreRuntimePoolItem脚本
代码为缓冲池预加载对象:这是PreRuntimePoolItem脚本的作用,SpawnPool下的Options预设必须包含prefabName,并且悬挂PreRuntimePoolItem脚本的对象和SpawnPool脚本下的Options中的预设无关!
如果SpawnPool脚本下已经有预设为Cube的对象,并且预加载数量为3,如果此时我们通过 PreRuntimePoolItem脚本的作用,也为此缓冲池加载了2个预设为Cube的对象,那么即使PreRuntimePoolItem脚本的Do Not Reparent是否勾选,一旦程序进行Spawn获取,那么这些预加载对象都会被加载到挂有SpawnPool脚本的对象下,如果Spawn50个,那么就会依次**他们!Despawn On Start为true的不会算在内!
取缓冲池中的某一个对象
Transform cubePrefab = PoolManager.Pools["Shapes"].prefabs["Cube"]; Transform cubeinstance = PoolManager.Pools["Shapes"].Spawn(cubePrefab); cubeinstance.name = "Cube (Spawned By CreationExample.cs)";
项目实例:
首先就是Unity布局:简单搭建如下图所示的场景。
脚本代码:
using UnityEngine;
using System.Collections;
using PathologicalGames;
public class NewBehaviourScript : MonoBehaviour {
SpawnPool spawnPool;
PrefabPool refabPool;
public Transform myTran;
int count = 0;
bool isShoot = false;
public GameObject ShootCube;
void Start()
{
spawnPool = PoolManager.Pools["Shapes"];
refabPool = new PrefabPool(Resources.Load<Transform>("momo"));
intT();
}
void intT()
{
refabPool = new PrefabPool(Resources.Load<Transform>("momo"));
//默认初始化两个Prefab
refabPool.preloadAmount =1 ;
//开启限制
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]);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Transform momo = spawnPool.Spawn("momo");
momo.transform.position = myTran.position;
momo.transform.forward = myTran.forward;
ShootCube = momo.gameObject;
count++;
isShoot = true;
if (count>=5)
{
spawnPool.DespawnAll();
intT();
count = 0;
}
}
if (isShoot)
{
ShootCube.transform.position += new Vector3(0, 0, 5f);
}
}
}
效果展示:
通过创建缓冲池,并缓冲需要的对象,可以达到Objectpool 的效果,大大提高实例化的速度和节省内存空间。
下面的连接带有Demo,可以直接使用。
缓冲池资源连接(已经修改导入报错的bug,大家可以放心使用,要不导入高版本的Unity会报错。):