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()方法,进行比如:清理状态、注销事件和释放使用过的资源等。然后将对象重新放入对象池中,等待下次复用。
总结
通过这种方式去管理游戏中的对象,可以减少了对象频繁创建的性能开销,进而避免游戏卡顿。
热门推荐
Alloy500铜镍合金国标的拉伸性能
贵阳合伙企业分支机构变更登记办理指南(流程、材料、地点、费用、条件)
个人公积金开户及申请交公积金的方法与要求
INFP人格类型的特点、适合职业及职业选择建议
肝癌的微创消融治疗:多种选择,各具优势
肝癌的介入手术是什么
蛇的别称(图)
神经敏感度过高怎么办?专业医生给出三大应对方案
Excel剪切一行粘贴到另一行的详细教程
餐后血糖用这几个方法搞定,医生都在用!
深度求索AI技术:开启高精度地震预测的新纪元
国企员工跳槽到外企,需考虑职业发展、薪资待遇、工作文化等因素
宝宝防蚊虫叮咬什么产品好用 宝宝被蚊子咬怎么办
深度学习模型命名的艺术:如何起一个既专业又吸引人的名字?
深度学习模型命名的艺术:如何打造既高大上又实用的模型名称?
揭秘YouTube限流:原因与解决之道大解析
杭州已开通快速路512公里,在飞驰中,城市焕发新活力
一天的跟拍:刑事执行检察官的工作日常
立秋时节咋养生:因人而异适当补 伏天晒背有讲究
【OpenFOAM案例研究】:真实世界问题模拟解决方案的深度剖析
STM32 IAP应用开发——自制BootLoader
在Keil中使用ST-LINK烧录STM32程序指南
香港十大经典药品:从百年老字号到家庭必备良药
在香港注册商标:全面指南与实用建议
从0入门C语言,看这5本经典书就够了!
法院受理案件需要多钱?全面解析诉讼费用收取标准与法律规定
体检常查的“肿瘤标志物”:查得越多越好?指标异常就代表患癌?
看江西永新县如何利用区域资源禀赋发展清洁能源
癌症发生的演变:四个理论
如何查询公司信用记录?多种渠道全方位指南