简单对象池的制作
关于对象池的介绍和讲解网上有很多,这里就不进行赘述。考虑到插件以后可能会进行修改或扩展,所以我需要使用泛型,然后初步确定对象池需要有取出、回收和清空三个功能。所以代码如下:
public class ObjectPool<T> where T : class
{
private PoolItemBase<T> _itemPrefeb;
private Queue<T> _poolQueue;
public ObjectPool(PoolItemBase<T> item)
{
}
/// <summary>
/// 从池子中获取对象
/// </summary>
/// <returns></returns>
public T GetObject()
{
}
/// <summary>
/// 将对象回收进池子
/// </summary>
/// <param name="tList"></param>
public void RecycleObject()
{
}
/// <summary>
/// 清空池子
/// </summary>
public void ClearPool()
{
}
}
其中考虑到不同类型的对象可能实例化或者消失显示的方式不同,所以创建了一个PoolItemBase类作为池子的存储对象,这个类也是泛型,里面主要有实例化、隐藏、销毁和显示的方法,池子只需要调用对象的相应方法即可;此外在构造的时候需要有一个prefeb参数作为模板,创建了一个泛型的prefebObj变量进行存储,以后池子创建出来的元素全部以此为模板(总感觉这个变量的存在不太好,但是想来想去想不到应该怎么去掉,这里先备注想到好办法在进行修改)。
public abstract class PoolItemBase<T> where T : class
{
protected T prefebObj;
public abstract T InstallNewItem();
public abstract void UnActiveItem(T t);
public abstract void DestoryItem(T t);
public abstract void OutPoolEvent(T t);
}
此基类的使用也很简单,只需要在继承的时候通过构建函数为prefebObj变量赋值,然后重写里面的方法就好了。放出测试的代码让大家看一下
public class GameObjectPoolItem : PoolItemBase<GameObject>
{
public GameObjectPoolItem(GameObject prefeb)
{
prefebObj = prefeb;
}
public override void DestoryItem(GameObject obj)
{
Object.Destroy(obj);
}
public override GameObject InstallNewItem()
{
return Object.Instantiate(prefebObj);
}
public override void OutPoolEvent(GameObject t)
{
t.SetActive(true);
}
public override void UnActiveItem(GameObject obj)
{
obj.SetActive(false);
}
}
至此,只需要在池子的函数中填充对应的逻辑就完成啦!完整代码如下:在测试的时候发现池子每次在回收的时候需要从管理的列表中拿出一个元素,然后再需要手动将该元素从管理列表中删除好麻烦,所以在回收的方法中添加了一个list变量,再通过ref关键字返回,这样在回收的时候只需要将对象列表传进去池子就可以自动回收并修改列表,操作简单了许多。
public class ObjectPool<T> where T : class
{
private PoolItemBase<T> _itemPrefeb;
private Queue<T> _poolQueue;
public ObjectPool(PoolItemBase<T> item)
{
_itemPrefeb = item;
_poolQueue = new Queue<T>();
}
/// <summary>
/// 从池子中获取对象
/// </summary>
/// <returns></returns>
public T GetObject()
{
T t;
if (_poolQueue.Count > 0)
{
t = _poolQueue.Dequeue();
}
else
{
t = _itemPrefeb.InstallNewItem();
}
_itemPrefeb.OutPoolEvent(t);
return t;
}
/// <summary>
/// 将对象回收进池子
/// </summary>
/// <param name="tList"></param>
public void RecycleObject(ref List<T> tList)
{
if (tList.Count>0)
{
_itemPrefeb.UnActiveItem(tList[0]);
_poolQueue.Enqueue(tList[0]);
tList.RemoveAt(0);
}
}
/// <summary>
/// 清空池子
/// </summary>
public void ClearPool()
{
for (int i = 0; i < _poolQueue.Count; i++)
{
_itemPrefeb.DestoryItem(_poolQueue.Dequeue());
i--;
}
}
}
测试一下,效果完美。