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()
方法,进行比如:清理状态、注销事件和释放使用过的资源等。然后将对象重新放入对象池中,等待下次复用。
总结
通过这种方式去管理游戏中的对象,可以减少了对象频繁创建的性能开销,进而避免游戏卡顿。
热门推荐
20个Word文档整理小妙招,让你秒变职场达人!
张鲁一版秦始皇引发争议:谁才是最帅的“千古一帝”?
关于奥斯卡奖,需要知道的事
SMTP服务器端口:深度解析与优化建议
《XX》剧集信息不足,无法创作
双性化人格:心理特征大揭秘
用矮盆养出爆花三角梅的秘诀
重庆一女生素来三角梅客厅走红!
年轻人怎么不结婚了?聊聊不婚主义兴起的原因
工资分开发放的税务筹划新招!
老年人如何用好商业医疗保险?
2025春节档票房破95亿:政策补贴、家庭观影与小镇影院如何助推新纪录?
长沙楼市2024新趋势:绿色智能住宅崛起
双十一理财狂欢:如何控制投资情绪?
实验教学法:让物理学习不再难
物理学家首次制出单个多原子分子的光镊阵列
保健品市场的乱象
宝宝吃奶摇头怎么回事
海鲈鱼PK金鲳鱼:谁更营养?
如何让男友晚归不再让你焦虑?
你的六年欠条还有救吗?
28岁是女生最佳结婚年龄?心理学研究给出惊人答案!
Postman & RestAssured:高效API测试神器
诗意昵称:解码当代人的精神追求
双11调查:低俗直播危害青少年心理健康
穿越牛熊:A股市场历次牛市深度回顾
意大利海岸路:地中海风情游
5x5训练计划:短时间内增肌的有效法则
高一数学错题分析与学习方案:从知识漏洞到系统提升
少林僧人的《易筋经》养生秘籍