前言
我们有一个用Unity引擎开发了二十个月的mmo arpg手游项目,在安卓已经测试三轮了,出于IOS的热的考虑且结合我们的情况:全部代码都是纯C#开发非Lua,所以计划使用ILRuntime热更,这里记录我们把这个项目用上ILRuntime热更的过程,包括遇到的困难和如何解决的。其它类型项目或其它项目架构的重点问题可能不一样
项目环境:ILRuntime版本 1.6.3 , Unity版本:2018.4.15f1
ILRuntime热更遇到问题
把项目大部分代码都搬到ILRuntime执行后,先说说从表现上我们遇到的问题:
GC Allow非常频繁
每隔5秒左右就会执行一次GC Allow,每次耗时200ms导致降帧,在手机上的GC Allow间隔时间会长一些
对象管理耗时
每个对象的update耗时在0.5~1ms,当场景内有100个对象时,只有几帧,基本卡住不动了。
对象管理耗时主要分布在对象的状态维护,对象显示/隐藏,头顶文字处理
空函数调用
一些空的Update函数调用,耗时在0.7ms
资源创建和销毁
在战斗过程中,技能特效的加载和创建第一次会顿一下
多人帧率低
场景内多人移动时,帧率会降低
界面打开瞬间掉帧
在界面第一次打开时,掉帧特别明显,这是因为在界面打开时有很多的逻辑
官方建议这些内容放主工程
通过咨询ILRuntime的作者蓝大,他建议把这些内容放在主工程
- 移动
- 资源管理
- UI框架
- 头顶文字
- 战斗(视情况是否放主工程)
- 对象管理放主工程
而我们项目由于完成度高,代码交叉调用多,只有极少部分内容放在主工程,其它内容全部放在热更工程中
通过Profiler看问题
好在是C#代码,把热更代码生成dll之后,在Unity的Profiler中查看耗时大的函数,可以看到具体的文件和函数名,这为排查重点耗时大户提供了极大的便利。
通过在Profiler中看到最大头的部分:
- 游戏中每个对象的update函数
- 红点检测会频繁遍历背包
- 一些网络包的处理
- 某些逻辑代码存在重复注册事件,或多次进入玩法出现函数重复调用
为什么对象的Update耗时会这么大?因为在主城中,一个地图中所有的npc,传送点,采集物都是由客户端本地管理,就算不在视野内也会执行Update,只是外观不显示。
而玩家则是由服务器的视野来控制,不在视野内的对象不会存在于客户端。
我们的解决方案
目前我们已经采取的解决方案有这些:
-
每个对象的Update进行分帧处理,不在同一帧处理,注意:仅对静止对象这样处理
-
去掉空的Update
-
把foreach改成for
-
把全局变量改成局部变量
-
修改红点的部分逻辑,避免每秒计算结果