简述:实现一个简易的PoolManager为游戏中生成对象节省内存。PoolManager做成一个单例。
功能简述:游戏中需要生成某些对象时,会先从pool中查看有没有这个对象。如果有的话就,就直接设置池子里这个对象的状态;若没有,则将该对象的状态设置成false。
下面就是一个最最最基本的PoolManager的功能实现,可以作为一个原型来参考。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class PoolManager : MonoSingleton<PoolManager> {
public int poolSize;
[HideInInspector]
public Dictionary<Type, Queue<GameObject>> Pool = new Dictionary<Type, Queue<GameObject>>();
[HideInInspector]
public Dictionary<Type, Queue<GameObject>> UnActivePool = new Dictionary<Type, Queue<GameObject>>();
public void AddToPool(Component c,GameObject go)
{
if (!Pool.ContainsKey(c.GetType()))
{
Pool.Add(c.GetType(), new Queue<GameObject>(poolSize));
UnActivePool.Add(c.GetType(), new Queue<GameObject>(poolSize));
Debug.Log("Add a Pool :" + c.GetType().Name);
}
}
public GameObject CreatPoolObject(GameObject prefab)
{
Component c = prefab.GetComponent<PooledObect>().type;
GameObject go;
if (!Pool.ContainsKey(c.GetType()))
{
go = GameObject.Instantiate(prefab) as GameObject;
AddToPool(c, go);
}
else
{
if(UnActivePool[c.GetType()].Count == 0)
{
go = GameObject.Instantiate(prefab) as GameObject;
}
else
{
go = UnActivePool[c.GetType()].Dequeue();
}
}
go.SetActive(true);
Pool[c.GetType()].Enqueue(go);
return go;
}
public void StoreObject(GameObject obj)
{
Component c = obj.GetComponent<PooledObect>().type;
if (UnActivePool.ContainsKey(c.GetType()))
{
UnActivePool[c.GetType()].Enqueue(Pool[c.GetType()].Dequeue());
}
}
}
下面一段脚本的作用是,在游戏中,我们给所需要加入对象池的游戏加入这个脚本。那么任何需要加入对象池的对象都会自动的被对象池所管理了
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("PoolObject")]
public class PooledObect : MonoBehaviour {
public Component type;
void Start()
{
}
void OnDisable()
{
PoolManager.Instance.StoreObject(this.gameObject);
}
}
功能描述:
这个对象池继承自一个单例Mono类
它的作用是对象池管理器会根据当前的类型,来自动创建一个对应的容器。这里我们用两个队列来表示对象池,一个队列存放被激活的对象,另外一个队列存放未被激活的队列。
每当我们需要增加的时候加入对象的时候会判断未激活的队列中有没有可以生成的对象,如果有,就直接激活一个提供使用,如果没有就新生成一个对象。这样即省内存,又不需要花大量的时间去查找未激活的对象
若我们的对象池管理器没有发现对应的对象池子,则会新生成一个对应类型的池子。
anyway,上面足够满足我们日常使用了。
不足:
没有扩容功能,一旦大起来了,就一直那么大
队列的最大容量设置要小心,一旦超过最大容量,就不能生成回收新的对象了。