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()
方法,进行比如:清理状态、注销事件和释放使用过的资源等。然后将对象重新放入对象池中,等待下次复用。
总结
通过这种方式去管理游戏中的对象,可以减少了对象频繁创建的性能开销,进而避免游戏卡顿。
热门推荐
如何选择电子天平
如何判断服务器是否在局域网
英语: 探讨 "What in the world" 的用法与含义
房屋租赁合同如何涨租金
方言俗字的构造与考辨
新马泰签证办理全攻略:材料清单、办理时间和注意事项一文详解
枕头填充物用什么比较好?五种常见材质优缺点全解析
如何通过日常习惯改善肺功能
有关意识的几个概念介绍(身边的心理学)
离婚中的心理支持与法律援助
日常有这些习惯的人,做好静脉曲张预防,出现6类症状,及时就医
鲜美好喝,蘑菇鸡蛋汤的烹饪小技巧
学霸背单词的秘诀:如何通过创新学习方式提高记单词的效率
耳朵痒的多种原因及有效应对方法解析
打豆浆时,用生豆子还是熟豆?做错了,难怪豆浆口感差还有豆腥味
慢性失眠:要重视
MBTI性格测试中的八维理论
西安城市发展新篇章:基础设施助力特大城市转型
古人为什么不伪造圣旨传达命令?从而达到自己的目的呢?
心肺复苏怎么做?急诊科医生为您解答
如何评估供应链质量管理的绩效?
静脉曲张初期忽视不管,竟暗藏致命危机?这三个预防动作快收藏!
猫咪跑了怎么办?教你有效寻找和安抚小猫的方法
丢猫丢狗催生“宠物侦探”,专家提醒:寻宠前先签协议
物权与债权的区别及合法讨债方式
中医药辅助管理高血压的“智慧”
地球的历史—认识沉积岩
肾血管疾病患者的社交支持及互助组织介绍
科学饮食与运动小技巧,助你轻松实现小蛮腰梦
计算冲量的方法是什么?这个概念如何应用于物理学?