前言
来源:https://www.bilibili.com/video/BV1C441117wU?p=2:
一、缓存池是什么?
缓存池:简而言之就是一个容器,你需要什么东西就在容器里面去拿,如果没有就创建,你用了的东西不用了就放回容器里面。缓存池可以将你创建的对象在你用完后收录起来,等到你再要调用的时候,就可以直接调用缓存池中收录的对象,如此往复,形成闭环。不必再去申请新的内存。Unity每一次创建对象,实际都是C#在内存中申请了一块空间,之后在Unity场景中Destroy这个物体对象,实际上只是断开了实例化对象对于内存的那块空间的一个引用,内存中依然存在那个对象对应的空间。直到内存占用满了,CPU才会回过头来找内存中没有被引用的空间(一次GC),然后释放该空间,然后建立新的对象,如此往复。这个GC步骤是比较消耗CPU的,所以在比较不好的机器上可能造成游戏的卡顿,所以,我们需要缓存池。
需要提前具备的知识点:
1.Dictionary和List
2.GameObject和Resources相关
二、使用步骤
1.缓存池简易代码
代码如下(示例):
public class PoolManager : SignleBaseManager<PoolManager>
{
public Dictionary<string, List<GameObject>> poolDic = new Dictionary<string, List<GameObject>>();
//从池子里面拿东西
public GameObject GetObjFromPoor(string name)
{
GameObject obj = null;
if (poolDic.ContainsKey(name) && poolDic[name].Count > 0)
{
obj = poolDic[name][0];
poolDic[name].RemoveAt(0);
}
else
{
obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
obj.name = name;
}
//将从池子拿出来的东西放在一个父节点下,便于管理
obj.transform.parent = GameObject.Find("PoorActiveTrue").transform;
obj.SetActive(true);
return obj;
}
//把东西往池子里面放
public void PushObjToPoor(string name, GameObject obj)
{
obj.SetActive(false);
//放回池子的东西放在一个父节点下,便于管理
obj.transform.parent = GameObject.Find("PoorActiveFalse").transform;
if (poolDic.ContainsKey(name))
poolDic[name].Add(obj);
else
poolDic.Add(name, new List<GameObject>() { obj });
}
//清理池子
public void PoolClear()
{
poolDic.Clear();
poolDic = null;
}
}
2.缓存池的使用
代码如下(示例):
public class UsePool: MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0))
PoolManager.getInstance().GetObjFromPoor("ResTest/Cube");
}
}
3.缓存池里面拿出来的物体延迟销毁(使用协程)
public class PushObj : MonoBehaviour
{
public float delayTime = 1;
void OnEnable()
{
StartCoroutine(PushObjToPoor(delayTime));
}
public IEnumerator PushObjToPoor(float time)
{
yield return new WaitForSeconds(time);
PoolManager.getInstance().PushObjToPoor(this.gameObject.name, this.gameObject);
StopCoroutine(PushObjToPoor(time));
}
}
4.缓存池里面拿出来的物体延迟销毁(使用Invoke函数)
public class PushObj : MonoBehaviour
{
public float delayTime = 1;
void OnEnable()
{
Invoke("PushObjToPoor", delayTime );
}
void PushObjToPoor()
{
PoolManager.getInstance().PushObjToPoor(this.gameObject.name, this.gameObject);
}
}
总结
优点:减少内存消耗、优化项目运行时的效率、防止内存泄漏:
相关链接
Unity程序基础框架__单例基类模块
Unity程序基础框架__缓存池模块
Unity程序基础框架__事件中心模块
Unity程序基础框架__公共Mono模块
Unity程序基础框架__场景切换模块
Unity程序基础框架__资源加载模块
Unity程序基础框架__输入控制模块
Unity程序基础框架__事件中心模块基类优化
Unity程序基础框架__音效管理模块
Unity程序基础框架__UI管理模块