zoukankan      html  css  js  c++  java
  • 提高Unity编译dll的速度

    前言

    我们有一个Unity纯C#开发的mmo项目(使用ILRuntime热更,开发阶段跑纯C#),在开发到后期之后,每次修改C#代码编译时间在25秒左右,这部分的等待时间是很长的, 我在想有没有办法可以缩短这个编译时间。

    编译dll时间分布:

    1. assembly-csharp 20s
    2. assembly-csharp-editor 0.88s
    3. assembly reload 4.08s

    如果把逻辑代码,抽离出来不放在Unity的目录下,通过visual studio编译这部分代码花费10s,抽离之后Unity编译时间为5s。也就是热更代码放Unity之后 assembly reload的时间变长了很多。

    项目代码构成:

    1. 不可热更代码,放在Unity的Asset目录
    2. 可热更代码也是C#,通过ILRuntime热更

    完整项目的Assembly-CSharp.dll有12.9MB,主要是protobuf的协议和配置表的entity数量非常多,还有非常多的养成系统代码,因为mmo游戏内容量很大。

    当然在这之前我已经尝试过使用asm,因为这个项目有很多代码之间是相互依赖的,只有少部分代码进行asm化了,所以我想尝试还有没有其它可以缩短编译时间的方法。

    Unity官方的增量编译

    Unity2018.1官方提供增量编译插件,见Unity论坛:https://forum.unity.com/threads/unity-incremental-c-compiler-deprecated.523993/

    在Unity的manifest文件中添加以下内容

    {
        "dependencies": {
            "com.unity.incrementalcompiler": "0.0.30"
        },
        "registry": "https://staging-packages.unity.com"
    }
    

    注意:目前官方已废弃此插件,原因是Unity2018.3中使用的C# 编译器比以往提高了5倍的速度,官方认为已经没有必要使用这个插件了,并且移除了这个插件。

    而且我在Unity2019.3.7f1中添加上述package无效。

    官方移除此插件的原话:https://forum.unity.com/threads/unity-incremental-c-compiler-deprecated.523993/page-9

    You should not be using incremental compiler when you are using Unity 18.3. In terms of compilation speed, 18.3 is very very close to Incremental compiler speed and a lot more robust

    Unity官方的其它做法

    在unity的文档中还提到这两种可以减少dll的编译时间:

    1. 把第三方库或不常改动的代码放到 Standard Assets或Plugins 目录下,这两个目录下的代码会最先编译,且不能依赖于外部其它脚本

    2. 尽可能多的使用asm,在Unity2018.2中已支持。

    注意:建议每一个asm中的代码是独立的,不依赖于外部,虽然Unity2019之后的版本asm之间可以相互引用

    关于asm可以参考我的这篇博客《Unity的asm笔记

    增量编译或动态加载dll

    微软的Roslyn

    通过Roslyn构建自己的C#脚本 看起来像和lua一样,执行字符串就可以执行C#代码,看起来可以做到在修改C#的情况下不重新Unity Play就能执行,看完文章之后我还没有去研究。

    Roslyn是.NET编译器平台,是微软的一组用于C#和VB语言的开源编译器和代码分析API,可以通过传统的命令行程序使用这些编译器,也可以通过.NET代码从本地获得这些API。Roslyn公开了用于代码的语法(词法)分析,语义分析,对CIL的动态编译以及代码发出的模块。

    罗斯林(Roslyn)最显着的主要特征包括:

    • 通过API公开为服务的C#和Visual Basic语言的编译器。
    • 用于代码分析和重构的API 。

    关于Roslyn的介绍摘自维基百科:Roslyn(编译器)

    github增量编译库

    Unity3D.IncrementalCompiler

    从提交记录来看只支持到Unity5,在github找到另一个fork者的库已支持unity2018,但是clone下来后没有编译成功dll,所以放弃了。

    网上搜索Roslyn Unity也是只支持到Unity5

    插件

    Roslyn C# - Runtime Compiler :收费插件,价格20美金

    *Requires .Net 4.x API compatibility level*

    Roslyn c#允许使用Roslyn编译器在运行时加载程序集和c#脚本,使您可以轻松地向项目添加modding(改装)支持或游戏内编程。此外,Roslyn c#还包括代码安全验证,允许您指定加载的代码必须遵守的许多安全限制,包括非法的名称空间和类型。这使得从未知来源加载第三方代码更加安全。包括一个基于小程序设计的游戏,其目标是通过编写执行方向决策的代码来导航鼠标走出迷宫。

    查看Unity编译dll的耗时分布

    Compiling Indicator - Wait Relaxed 免费插件,功能介绍:

    编译指示器是一个小的通知窗口,当Unity编辑器开始编译时弹出。它显示了编译的进度和估计的完成时间。您还可以找到占用项目编译时间最多的程序集。

    编译指示器了解项目的编译时间。因此,它的估计将会变得正确,因为它经历了更多的编译。您所要做的就是等待,直到编译指示器掌握了足够的信息。或者,要重置已学习的信息,您可以单击“清除数据库”按钮。

    使用方法:导入到Unity之后,当C#代码有修改时,在右下角会弹出编译进度,编译完成之后点击一下就可以关闭

    image-20210511094543605

    目前我的做法

    放在Standard Assets

    经过上面的尝试之后,目前是把用到的2个插件放在Standard Assets目录下,对sharpzip进行asm化,编译时间基本保持在24秒左右。

    把框架代码asm化

    框架代码抽出到独立目录中,进行asm化,关于asm可以参考我的这篇博客《Unity的asm笔记

    去掉不使用的package

    去掉package.json中不需要用到的库,我在项目中只留下了package manager ui,时间减少了0.5s

  • 相关阅读:
    Building a flexiable renderer
    Indirect Illumination in mental ray
    我的心情
    Cellular Automata
    Subsurface Scattering in mental ray
    Shader Types in mental ray
    BSP Traversal
    我的渲染器终于达到了MR的速度
    How to handle displacement and motion blur
    说明
  • 原文地址:https://www.cnblogs.com/zhaoqingqing/p/14757149.html
Copyright © 2011-2022 走看看