提供一个小demo来创建并使用缓存池
鼠标左右点击分别在场景中生成对应的预制体,在物体生成一段时间(1s)之后自动进行销毁(返回到缓存池)
无论要生成多少个对象,Hierarchy面板中只有一定的数量的对象产生,实现对对象池的使用。
下面是相关的脚本:仅供学习参考
1.单例脚本基类
/// <summary>
/// 单例模式基础脚本
/// </summary>
public class BaseSingleton<T> where T : new()
{
private static T instance;
public static T Instcance
{
get
{
if (instance == null)
instance=new T();
return instance;
}
}
}
2. 对象池 注释很详细哦!
using System.Collections.Generic;
using UnityEngine;
namespace ProjectLearn
{
/// <summary>
/// 对象池实现 单例实现
/// </summary>
public class ObjectPool:BaseSingleton<ObjectPool>
{
//对象池使用字典和List实现
//字典存储对象种类(名称)和存储对象个体的List的对应关系
//List存储对应的对象实例
public Dictionary<string, List<GameObject>>
poolDic = new Dictionary<string, List<GameObject>>();
/// <summary>
/// 根据对象名称(种类)从对象池中获取对象
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public GameObject getObj(string name)
{
GameObject obj = null;
//判断对象池是否满足获取条件
if (poolDic.ContainsKey(name) && poolDic[name].Count > 0)
{
//获取时候从对象池(List)的头部获取
obj = poolDic[name][0];
poolDic[name].RemoveAt(0);
}
else
{
//若对象池中暂且未存储(第一次产生时候)从资源中加载生成对应的预制体
obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
//物体的名字保持和对象池存储的名字一致
obj.name = name;
}
//激活对象
obj.SetActive(true);
return obj;
}
/// <summary>
/// 将不用的对象返回存储到对象池中
/// </summary>
/// <param name="name"></param>
/// <param name="obj"></param>
public void pushObj(string name,GameObject obj)
{
//如果对象池为空-创建对应存储的对象池
//若存在对应的对象池(List)
//先失活
obj.SetActive(false);
if (poolDic.ContainsKey(name))
{
poolDic[name].Add(obj);
}
else
{
//若没有对应存储的对象池
//新建 并将本身存储进去
poolDic.Add(name,new List<GameObject>(){obj});
}
}
/// <summary>
/// 清空缓存池
/// </summary>
public void Clear()
{
poolDic.Clear();
}
}
}
3. 测试脚本挂在场景中空物体上
using ProjectLearn;
using UnityEngine;
public class Test : MonoBehaviour
{
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
ObjectPool.Instcance.getObj("Test/Cube");
}
if (Input.GetMouseButtonDown(1))
{
ObjectPool.Instcance.getObj("Test/Sphere");
}
}
}
3.挂载预制体上
using UnityEngine;
namespace ProjectLearn
{
/// <summary>
/// 控制对象销毁(返回到)缓存池中
/// </summary>
public class pushPool:MonoBehaviour
{
private void OnEnable()
{
//两秒后自动归到缓存池
Invoke("pushBack",1);
}
void pushBack()
{
ObjectPool.Instcance.pushObj(gameObject.name,gameObject);
}
}
}
预制体的放置: