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()方法,进行比如:清理状态、注销事件和释放使用过的资源等。然后将对象重新放入对象池中,等待下次复用。
总结
通过这种方式去管理游戏中的对象,可以减少了对象频繁创建的性能开销,进而避免游戏卡顿。
热门推荐
小红书春节营销:拉新与直播双管齐下,下沉市场渗透效果几何?
元旦打卡:豫园&城隍庙,穿越千年的文化之旅
俞敏洪打卡!武汉地道美食指南
丽江日照金山打卡攻略:拍出绝美大片!
秋冬打卡丽江:白沙古镇日照金山绝美时刻
丽江日照金山:打卡幸运之旅
节后返工日寒潮来袭!这份防护指南请收好
湖北新晋4A景区:樟蜜小镇·白崖山景区
春节打卡黄鹤楼,感受英雄城市魅力!
深度学习框架:Caffe、TensorFlow、PyTorch 比较
南粤古驿道:一条贯穿岭南两千年的文化长廊
秋冬自驾游:广州到郴州必打卡景点推荐
2025年中国消费升级十大趋势:从品质觉醒到心界重塑
瓦罐汤&拌粉:南昌人的舌尖乡愁
冬日避寒胜地:庐山&婺源古村落
武山水帘洞石窟:丹崖地貌中的石窟艺术瑰宝
红枣功效与禁忌:一天吃几颗?哪些人不适合吃?
金樱子:一种具有多重功效的中药材
南雄市春节特色活动大揭秘!
这个周末,打卡成都周边绝美自驾游胜地!
写给新手的日本自由行攻略大全!机票住宿、交通、行程安排总整理
日本留学交通全攻略
异物卡喉不要慌,学会一招能救命——海姆立克急救法详解
气管吸入异物怎么办?五种有效处理方法
大皮院:西安必尝地方小吃推荐!
从钟鼓楼到回民街:西安的烟火气与古韵交织
福州十大公园推荐:城市中的“森林精华”,点亮有福之州
广州东站直达潮汕动车,3.5小时美食之旅!
广州到潮汕自驾游:美食与风景的奇妙旅程
广州潮汕美食全攻略:从砂锅粥到卤水鹅,带你寻觅最地道的潮汕味道