标签:evel list opera style rip directory import file 字段
Unity3D 引擎在 UnityEngine 名字空间下,提供了 Profiler 类(Unity 5.6 开始似乎改变了这个名字空间),用于辅助对项目性能进行测试。以 Android 平台为例,在构建之前,需要在 Unity 的 File/Build Settings 菜单项弹出的窗口中,勾选 Development Build 一项。后用 adb forward 的方式,将 Android 设备的 TCP 输出转发到电脑,实现和 Unity Profiler 的连接(网上很容易找到这个过程的具体描述,如这里)。但是 Unity Profiler 默认只提供部分方法/函数,尤其是 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 作为 Scripting backend。也就是说,安装入 Android 设备的 apk 包中是带有 C# 程序集的,而程序集中其实是 IL 代码。为了方便,在 Unity 的 File/Builde Settings 中,勾选 Google Android Project 一项,要求 Unity 不要直接生成 apk,而是生成 Android 工程。这样,在 Unity 的构建过程结束后,就可以使用 Cecil 在目标文件夹夹的 C# 程序集上注入代码。
如何注入呢?大体有几个要点:
使用 Cecil 的要点主要是:
var resolver = new DefaultAssemblyResolver(); // 搜索目标文件夹中的程序集来解析程序集外部的方法。 resolver.AddSearchDirectory(directory); var moduleDef = ModuleDefinition.ReadModule(assemblyPath, new ReaderParameters { AssemblyResolver = resolver });
var loadStr = Instruction.Create(OpCodes.Ldstr, myString);
instructions.Insert(0, loadStr);
var callBegin = Instruction.Create(OpCodes.Call, targetMethod.Module.Import(m_BeginSampleMethod));
instructions.Insert(1, callBegin);
在注入完成后,继续 Android 平台的原生构建生成 apk 包,安装进设备,将设备连接电脑,即可在 Unity 的 Profiler 窗口中看到新增的性能采样信息。
使用 Mono.Cecil 辅助 Unity3D 手游进行性能测试
标签:evel list opera style rip directory import file 字段
原文地址:http://www.cnblogs.com/jehovah0121/p/6844442.html