UnityEngineAnalyzer静态分析优化Unity代码
参考:https://zhuanlan.zhihu.com/p/27915954
鉴于这个链接中的内容比较早,一些知识点已经失效,比如构建方式,生成的EXE的目录等等
如何获得UnityEngineAnalyzer
当前活跃项目: https://github.com/vad710/UnityEngineAnalyzer
原始项目: https://github.com/meng-hui/UnityEngineAnalyzer
其他项目:https://bitbucket.org/kzoabi/unity3d-gendarme-plugin
静态代码分析比较著名的Lint可以检测出可能的空指针,拼写错误,除0等等。VS,还有VS的插件Resharper也带有静态代码分析的功能。
和一般的插件不同,UnityEngineAnalyzer可以分析一些Unity特有的一些性能和问题隐患,也支持自定义添加规则
为什么需要静态代码分析
- 提早发现代码中的BUG,避免将BUG带到生产环境
- 极大的提高软件质量,以及可维护性
- 统一代码规范、提高可读性,减少新加入成员的熟悉时间
- 加速个人和团队的成长,知识和经验的积累
- 节约有限的开发时间
- 避免人工检查的遗漏,不可能记住所有优化点也不能保证不遗漏
- 可以内建到CI系统(持续集成)
规范的项目一般会有代码审核,而代码审核分为人工审查和工具审查。人工审查方面目前每天会有代码Review,每个版本会做ProjectReview。但是人都会有疏漏,使用自动化的工具进行补充可以避免人工检查的漏洞和节省大量时间。
UnityEngineAnalyzer的优点
- 可以发现Unity特有的一些潜在问题,例如代码规范,性能问题
- 可以作为VS插件使用,也可以作为独立的程序单独执行
- 可以通过ComandLine执行
- 可以生成HTML报告
- 多平台支持
以下是他们官网的介绍:UnityEngineAnalyzer分析器是一套基于Roslyn分析程序,旨在检测Unity3D C#代码中的常见问题。Unity3D让我们很容易做跨平台游戏,但是有一些隐藏的规则例如性能和AOT等,会影响到程序的体验和测试等。我们希望这些问题能在编译之前被发现
UnityEngineAnalyzer的检查项
- 不允许直接Tag的比较,使用CompareTag代替直接比较减少GC;
- 不允许在Update中调用Find;
- 不允许有空的MonoBehaviour方法,例如Update,FixedUpdate,LateUpdate等;
- 不允许使用OnGUI,OnGUI会导致GC;
- 不允许使用Coroutine避免产生GC,这个目前使用的5.5.1版本已经修复不需要了;
- 不允许使用Foreach避免产生GC,这个目前使用的5.5.1版本已经修复不需要了;
- string方法
- Remoting(AOT),EmitCalls(AOT),GetType(AOT)
个人操作过程:
1、从git上获取到源码,https://github.com/vad710/UnityEngineAnalyzer,或者在https://github.com/vad710/UnityEngineAnalyzer/releases 直接获取二进制文件
2、安装环境,因为该项目使用了.NetCore2.1,建议安装vs2019或者自行安装Net库
3、进行编译,win10平台,进入cmd或者powshell,cd到项目解决方案所在的目录,比如我的目录是D:\GitHub\UnityEngineAnalyzer
dotnet publish -c Release -r win10-x64
然后等待发布就可以了,成功后可以在对应目录找到执行程序,UnityEngineAnalyzer\Linty.CLI\bin\Release\netcoreapp2.1\win10-x64
4、Run Linty.CLI.exe <project path> ,注意这里的工程目录是以xxx.csproj的文件目录,类似Linty.CLI.exe C:\Code\MyGame.CSharp.csproj,正确运行后会在对应的工程目录,也就是和Assets同级目录下生成两个文件report.json和UnityReport.html
里面有分析内容以及对应的建议和代码位置。需要注意的是html需要用FireFox浏览器打开,json可以直接浏览。原始工程的exe在执行的时候会报一些异常需要修改一下代码,主力工程不需要。
5、命令行中可选参数:
Use command -e customexporter exporter2 自定义导出目录
Use command -s Info/Warning/Error 减少导出项
Use command -v UNITY_2017_1/UNITY_5_5/UNITY_4_0/ 对应Unity版本的检索,具体版本号可以查项目的ProjectVersion.txt,默认情况他会读这个文件进行自动匹配
有两种方式可以制作插件集成到VS工程中,一个就是以NuGet package的方式,一个是另一种方式是编译成VSIX插件,安装到VS中对IDE下所有项目进行分析。
NuGet包,可以安装网上已有或者本地重新生成的
VSIX插件,安装到VS中对IDE下所有项目进行分析。只要编译UnityEngineAnalyzer.Vsix工程在bin中双击UnityEngineAnalyzer.Vsix.vsix安装即可,安装完毕可以在Tools/Extensions and Updates里看到。
重启VS之后在Error List就可以看到用户自定义的Unity特有的Wanrings了,如下图,不过我个人是不喜欢这种插件安装,更喜欢报告式的,保证VS输入清净点。
UnityEngineAnalyzer的扩展
我们可以对分析器进行扩展和修改。例如新版本的Unity不需要对Foreach等做限制,另外可以添加项目组自己的代码规范,代码风格,特定设置等
解决方案中的工程如下:
- Linty.Analyzers:这是主项目,构建包含诊断和代码修补程序的分析器 DLL
- Linty.CLI:这是可执行的exe
- UnityEngineAnalyzer.Test:这是单元测试项目,有一些测试用例便于调试
- UnityEngineAnalyzer.Vsix:这是制作用于VS的插件的项目,也是把dll绑定到VS中
DiagnosticIDs这个文件里可以自定义一些用户自己希望使用的警告标签,例如DoNotUseOnGUI = "UEA0001"
具体自定义扩展,可以参考,LintTy.Analyzers中的代码,其实结构还是很简单的。继承DiagnosticAnalyzer类,重写Initialize,中的注册方法,具体判断实在AnalyzeNode静态函数中。
当检测发现问题的时候则调用context.ReportDiagnostic(diagnostic)方法,抛出一个警告。参数diagnostic可以设置警告的标签,警告的内容,行号,类名等等。xxxx.resx文件,可以设置在错误列表中向用户显示标题,描述等
最后,其他更多的还没有做尝试,有问题可以共同探讨。