
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
今天昆明达内培训小编跟大家分享:如何实现用Mono.Cecil辅助Unity3D手游做性能测试?Unity3D引擎在UnityEngine名字空间下,提供了Profiler类(Unity5.6开始似乎改变了这个名字空间),用于辅助对项目性能进行测试。UnityProfiler默认只提供部分方法/函数,尤其是Unity内置方法/函数的性能采样,如果想Profile自己项目的代码段,就必须在代码段入口和出口加上:
Profiler.BeginSample("ProfilerName");
//代码段。
Profiler.EndSample();
对于一个已经进行了一段时间,有十几万行代码的项目,想逐个方法添加采样代码,甚至在加上预编译命令,是非常麻烦的,而且很容易出错。
幸好昆明达内官网小编遇到了Mono.Cecil这个库(github链接)。这个库所做的事情,并不难理解。我们知道C#通常编译为中间语言(IL),之后由.NET虚拟机对其进行执行。Cecil的一部分能力就在于,可以任意修改生成的IL。尽管.NET的Mono实现有很多缺陷,且Unity在iOS平台上早已推出IL2CPP机制,将IL转换为C++代码,再在目标平台进行原生的C++编译链接,但在Android设备上,大部分项目仍然使用Mono作为Scriptingbackend。也就是说,安装入Android设备的apk包中是带有C#程序集的,而程序集中其实是IL代码。为了方便,在Unity的File/BuildeSettings中,勾选GoogleAndroidProject一项,要求Unity不要直接生成apk,而是生成Android工程。这样,在Unity的构建过程结束后,就可以使用Cecil在目标文件夹夹的C#程序集上注入代码。
如何注入呢?
方法出口注入代码稍微有些麻烦。尽管IL级别的函数都是以一个返回指令结束的,但直接在返回指令之前插入新的指令是不够的。因为很多时候,返回指令是由跳转指令直接跳转过去的。而对于我们在C#中获取的指令容器,跳转指令保存了其跳转目标的引用。因此,我们不仅需要在返回指令前插入我们需要的指令(对Profiler.EndSample包装方法的调用),还要将跳转目标为该返回指令的跳转指令的目标,修改为我们新增的指令。这里有详尽的关于IL指令的列表。对应Cecil中OpCodes类中的常量,我们可以过滤出跳转指令,并用Operand属性获取或修改其跳转目标。
修改完成后,需要对当前的模块对象moduleDef调用moduleDef.Write(assemblyPath,newWriterParameters{WriteSymbols=true})来写回程序集文件。这个调用中,第二个参数的含义,是把新增的符号也写入程序集(比如我们调用的该程序集之外的方法)。
好了,以上就是小编要给大家分享的内容,详情请登陆达内昆明培训官网:http://km.tedu.cn