Unity开发中对象池设计与使用详解
创作时间:
作者:
@小白创作中心
Unity开发中对象池设计与使用详解
引用
CSDN
1.
https://blog.csdn.net/2301_79022588/article/details/146284488
在Unity开发中,对象池是一种常用的优化技术,用于管理游戏中的对象,避免频繁创建和销毁对象带来的性能开销。本文将详细介绍对象池的设计原理和具体实现方法,帮助开发者更好地理解和应用这一技术。
设计目的
为了避免频繁创建和销毁对象(例如 UI 元素、事件对象等)带来的内存分配和垃圾回收压力,可以使用对象池来管理对象来提高游戏的性能,避免游戏卡顿。
代码实现
public interface IRecycle
{
/// <summary>
/// 回池必须调用的接口
/// </summary>
public void OnRecycle();
/// <summary>
/// 初始化接口
/// </summary>
public void OnFetch();
}
public class CacheObjectMgr : Singleton<CacheObjectMgr>
{
private Dictionary<Type, Queue<IRecycle>> m_Gos;
protected override void OnInit()
{
base.OnInit();
m_Gos = new Dictionary<Type, Queue<IRecycle>>();
}
public T Fetch<T>() where T : class, IRecycle, new()
{
IRecycle obj = null;
Queue<IRecycle> pool = _GetPool(typeof(T));
if (pool.Count > 0)
{
obj = pool.Dequeue();
}
else
{
obj = new T();
}
obj.OnFetch();
return obj as T;
}
public void Recycle(IRecycle go)
{
if (go != null)
{
go.OnRecycle();
_GetPool(go.GetType()).Enqueue(go);
}
}
private Queue<IRecycle> _GetPool(Type type)
{
Queue<IRecycle> pool = null;
if (!m_Gos.TryGetValue(type, out pool))
{
pool = new Queue<IRecycle>();
m_Gos.Add(type, pool);
}
return pool;
}
}
代码分析
字典存储结构:使用
Type作为键,存储每种类型对应的对象池(队列)。这样不同类型的对象可以分开管理,且在回收和取用时无需强制转换。对象池的设计:每个队列中存储的都是
IRecycle类型的对象。由于 C# 支持接口的多态性,只要对象实现了IRecycle接口,就可以存入该队列中,而不需要关心具体的实现类型。这个接口定义了两个关键方法
OnFetch():在对象从池中取出时调用,用于执行初始化工作(例如重置状态、注册事件等)。OnRecycle():在对象回收前调用,用于清理或重置对象状态(例如注销事件、释放资源等)。Fetch 逻辑:方法约束:
where T : class, IRecycle, new()确保了被管理的对象必须实现IRecycle接口,并且可以通过无参构造函数创建。获取对象的方式:
- 通过
_GetPool(typeof(T))获取对应类型的对象池(如果不存在则创建新的队列)。 - 判断池中是否有可用对象:如果有则调用
Dequeue取出,否则通过new T()创建新对象。 - 调用对象的
OnFetch()方法完成初始化操作(例如注册事件、设置状态等)。 - 返回对象,并通过
as T进行类型转换。
- 通过
这种实现方式确保了在每次从池中取出对象前,都能通过 OnFetch 方法对对象进行了必要的初始化,保证对象处于可用状态。
该方法通过传入对象的类型来获取或创建对应的队列。
获取对象的方式:
- 判断是否存在该类型的对象池,如果不存在就创建该类型的对象池并将其添加到字典中。
- 如果存在就获取该类型的对象池。
回收对象的方法
该方法在对象使用完毕后,进行调用 Recycle 方法然后将对象放回池中。
- 判断对象是否为空
- 调用对象的
OnRecycle()方法:此方法通常用于清理、解除事件注册、释放使用过的资源等,这样可以确保对象在下次取用前处于一个全新的状态。 - 然后根据对象类型,调用
_GetPool(go.GetType())获取对应的队列,然后使用Enqueue将对象加入队列。
示例演示
关键步骤:
- 在类中去实现
IRecycle这个接口,实现这个接口就要去实现接口中所声明的所有方法。 - 在通过
Fetch方法创建对象时会调用该对象中的OnFetch()进行初始化。 - 回收方法实现:
- 在事件结束后调用
OnRelease进行回收,调用该方法会通过Recycle先调用OnRecycle()方法,进行比如:清理状态、注销事件和释放使用过的资源等。然后将对象重新放入对象池中,等待下次复用。
总结
通过这种方式去管理游戏中的对象,可以减少了对象频繁创建的性能开销,进而避免游戏卡顿。
热门推荐
南瓜子的作用与功效及禁忌,南瓜子一天吃多少合适?
孔子教你六十岁如何“耳顺”
济源出发6天自驾游云南:大理香格里拉行程与费用详解
珠海必游攻略:打卡世界奇迹大桥和海岛歌剧院
奥美拉唑被重点监管,如何避免副作用?
母爱的N种打开方式
泰国低收入群体的奢侈品情结解析
取消华为视频会员自动续费
喘憋伴双下肢无力,抗Jo-1/Ro-52双阳确诊ASS
“税路通”助力企业跨境税务管理
数十亿人将死于灾难性大洪水?他们唱着歌等待外星人救赎,结果……
埃及十大必看景点:从金字塔到绿洲,领略古埃及文明魅力
疾病小常识 | 保持乐观态度面对帕金森
水飞蓟素能护肝保肝,可以治疗脂肪肝、酒精肝,科学服用注意4点
人生有定数,因果皆是缘。
天津亲子游攻略:5大场馆激发孩子探索欲
国庆打卡内蒙古河口古镇:黄河边的历史文化之旅
河口古镇:千年商埠的茶道传奇与文化新生
破伤风免疫球蛋白的正确使用指南
化繁为简的数学妙招:理解等价替换,轻松解题
港大30人学历造假被捕,全球高校严查成常态
800万摄像头的家庭安防配置指南
《自然》发布XY染色体配对机制研究,为遗传病治疗带来新希望
海南岛旅游预算指南:4天3晚最低6000元起
冬季如何预防牙结石?专家支招全方位守护口腔健康
玻璃杯、飘逸杯、盖碗:茉莉龙珠茶的三种冲泡法
兔子频繁刨墙是怀孕信号,这些行为暗示它要生宝宝了
重型用6号,轻型用8号:液力传动油选购指南
法甲对决:里尔主场迎战南特,谁能笑到最后?
泰兴美食打卡攻略:香肠、大米、阳春面必吃!