unity中创建和销毁游戏物体都有较大的性能开销。因此,对于需要大量创建和销毁游戏物体的情况(如射击游戏中子弹不断生成和销毁),如果对每一个对象都进行创建和销毁会造成大量性能开销。为此,我们可以利用对象池进行对象的缓存和复用。
每当一个游戏物体要退出场景,我们不立刻将该对象销毁,而是将其储存到对象池里。当再需要出现同类对象时,我们先从对象池里获取之前存储的对象,如果对象池已空再创建新对象。
对象池类:
// object pool
public class PoolStack {
public Stack<UnityEngine.Object> stack = new Stack<Object>();
public int MaxCount = 100; // maximum objects in stack
// push gameObject into the pool
public void Push(UnityEngine.Object obj) {
if (stack.Count < MaxCount) {
stack.Push(obj);
} else {
GameObject.Destroy(obj);
}
}
// retrive gameObject from pool
public UnityEngine.Object Pop() {
if (stack.Count > 0) {
return stack.Pop();
}
return null;
}
// clear the pool
public void Clear() {
foreach (UnityEngine.Object obj in stack) {
GameObject.Destroy(obj);
}
stack.Clear();
}
}
在该对象池类中,我们使用一个栈作为对象池,并规定最大储存数量为100. 我们实现了对象池以下操作:
1 Push(): 将一个新对象加入对象池,如果对象池已满删除对象
2 Pop(): 从对象池返回一个对象,如果对象池已空返回null
3 Clear(): 清除对象池里面所有对象,并清空栈
由于游戏中可能需要为不同类型物体创建不同对象池,我们在对象池中使用数据类型UnityEngine.Object,所有游戏物体的父类。同时,我们需要一个对象池管理器用于管理所有对象池
public class PoolManager
{
private static PoolManager instance;
public static PoolManager Instance {
get {
if (instance == null) {
instance = new PoolManager();
}
return instance;
}
}
Dictionary<string, PoolStack> poolDic = new Dictionary<string, PoolStack>();
// retrive object from pool, otherwise create one object
public UnityEngine.Object Spawn(string poolName, UnityEngine.Object prefab) {
if (!poolDic.ContainsKey(poolName)) {
poolDic.Add(poolName, new PoolStack());
}
UnityEngine.Object obj = poolDic[poolName].Pop();
if (obj == null) {
obj = GameObject.Instantiate(prefab);
}
return obj;
}
// clear the object pool
public void UnSpawn(string poolName) {
if (poolDic.ContainsKey(poolName)) {
poolDic[poolName].Clear();
poolDic.Remove(poolName);
}
}
}
该类还是使用单例模式构造。创建一个字典用于保存各个对象池
1 Spawn:如果对象所对应的对象池不存在,则新建对象池。如对象池里没有该对象,生产对象,否则从对象池中取出
2 UnSpawn:删除一个对象池