Unity编辑器edit mode进入play mode时间优化
简介
最近需要利用他人打包好的资源,接近8G,不是很大,但解压完小文件特别多,到了unity里面会频繁显示repaint提示窗,降低了开发效率。
于是采用了进游戏即时解包的策略,虽然资源可以在需要时再加载,但资源的索引需要在进入游戏时就构建好。构建资源id到文件偏移位置的映射,单线程需要花费近30s。
作者首先通过了多线程处理多个资源包的方法,以及对IO进行了稍微优化,在打完包后能达到 平均时间8s 完成加载的效果。但不知道为什么,在编辑器中依然需要平均时间15s 左右的时间(不包含domain reload所需时间)。
接着又通过将计算结果以资产形式存储在场景中的方式,将进入play mode时间缩减到平均时间10s (包含domain reload所需时间)。
问题
从edit模式进入play模式后,需要解包索引部分的数据。构建资源id到文件偏移位置的映射,需要消耗大量的CPU资源。
解决方案
一开始想到的是利用多线程加速计算。但即使如此也无法达到预期的效果。
由于资源包不会发生变化,因此将计算好的数据保存起来,进入play mode的时候再【内存】读取也是一种可选方案。
比较直观的想法是将数据保存在编辑器环境,令其不受进入退出play mode的影响,以及修改代码导致的assembly reload的影响。
domain reloading
一开始查询到的资料和domain reloading相关。Domain reloading会重置你代码的状态,相当于你打包后第一次启动游戏。但Domain reloading会消耗时间,并且和代码文件的个数和复杂度成正比。
Domain reloading的细节可以看这篇文档,可以看到domain reloading会先执行从MonoBehaviours到AppDomain以及JITInfo的销毁操作,再执行从Assembly加载到Unity objects反序列化的初始化操作。
.
粗看的话,在编辑器中关闭domain reloading一方面可以保留我们的计算结果,另一方面可以省去domain reloading的开销,是一箭双雕之举。
但它无法避免修改代码带来的domain reloading,并且如果没有domain reloading提供的状态重置,那么我们需要手动重置游戏内状态,增加了额外的负担。
Unity native memory
根据Unity手册,场景和资产是存储在native memory的,我们可以将计算好的数据以资产或者场景的形式存储。这样当我们修改代码,或者进入游戏时,不会因为C#的domain reload而需要重新计算。
Unity stores the scenes in your project, assets, graphics APIs, graphics drivers, subsystem and plug-in buffers, and allocations inside native memory,
但此举似乎会增加 反序列化所需的时间,从而增加了domain reloading的开销。
另外场景中的脚本的字段如果太大也会导致编辑器卡顿,需要对其gameobject设置hideFlag,仅仅字段设置HideInInspector似乎不起效果。
总结
需要在游戏运营的前期就把控好资源的大小和个数。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!