Unity游戏框架学习笔记——02缓存池
缓存池
一如既往指路牌:https://www.bilibili.com/video/BV1C441117wU?p=3.
缓存池,一般也称是缓冲池、对象池等等,顾名思义是一个用于存放对象的池子。
解决的是重复生成和销毁某一类对象,导致频繁GC(Garbage Collection)以至于游戏过程中卡顿的问题。
原理
① 将频繁生成和销毁的对象,在生成,然后经过一系列操作之后,要进行销毁时,不将其销毁,而是将其隐藏,保存在场景中。
② 在下一次需要生成该类对象时,并不重新实例化,而是直接在缓存池内取出,将其重新激活,显示在场景中。
③ 对于缓存池内部,在第一次使用需要频繁创建和销毁的对象时,先判断缓存池内有无失活的对象,若无则创建一个用于存储该对象的池子。
④ 缓存的概念其实是:对于不用的对象,失活隐藏在场景中,那么对与下一次的同类对象创建来说,就相当于是一种预生成的缓存辣。
数据结构
根据上述的特点,需要缓存池功能是:
① 区分对象的类别的标识
② 存储这些对象的空间
那么可以想到的是缓存池的数据结构,应该是:字典Directory<key, value>
关键字是对象的分类,或者是该类对象的名称 String
键值是存储 GameObject 类型的列表List< GameObject >
缓存池特性
根据上述的描述,不同的对象有其对应的空间来存储,但管理这些池子的类只能有一个,而不是各个不同的对象有相应对象池的类。
因此,缓存池在场景里面只能有一个,池子里面存储则各种不通过类型的缓存对象,那么缓存池就是具有单例的特性嘛。
缓存池的优化
为了便于查看场景中不同对象的使用情况,在对象失活,存入缓存池时,不仅仅是归入场景中的Pool空物体的子物体,还添加一个和该类对象同名的父物体来挂载失活的对象用以分类,即Pool->对象同名空物体->对象。
可知,对象同名空物体是作为对象的父物体存在,那么在对象回收的时候,需要找到对应的父物体然后构建父子关系,因此对象和父物体应该存在对应关系,那么我么不妨把父物体和对象池封装在一起作为一个类,来实现再分类。
那么对应的数据字典也应该相应做出修改:
原来是Directory< String, List< GameObject > >
修改为Directory< String, SubPool >
SubPool 子对象池要包含:
① 回收时要挂载的父物体
② 相应的子对象池存储
代码
SubPool类
/// <summary>
/// 子对象池类
/// </summary>
public class SubPool
{
// 子对象池的根对象
public GameObject fatherObj;
// 子对象池里的list,存储失活缓存对象
public List<GameObject> poolList;
/// <summary>
/// 构造函数
/// 当归还对象但是子对象池不存在的时候时调用以初始化
/// </summary>
/// <param name="subObj">要归还的子对象</param>
/// <param name="poolObj">pool根对象</param>
public SubPool(GameObject sub