理解Unity脚本编译过程:程序集
https://docs.unity3d.com/Manual/script-compilation.html
关于Unity C#脚本编译的细节,其中一个比较重要的知识点就是如何自定义Assembly。
预定义的assembly
默认情况下,Unity会按照这个规则进行编译。
Phase | Assembly name | Script files |
---|---|---|
1 | Assembly-CSharp-firstpass | Runtime scripts in folders called Standard Assets, Pro Standard Assets and Plugins. |
2 | Assembly-CSharp-Editor-firstpass | Editor scripts in folders called Editor that are anywhere inside top-level folders called Standard Assets, Pro Standard Assets and Plugins. |
3 | Assembly-CSharp | All other scripts that are not inside a folder called Editor. |
4 | Assembly-CSharp-Editor | All remaining scripts (those that are inside a folder called Editor). |
根据阶段的编号,从上到下进行编译。
条件编译
可以通过与定义宏,进行条件编译。需要特别注意的是编辑器的情况,如果想要条件编译在编辑器模式下生效,宏定义修改后需要对脚本进行重新编译,否则条件编译不生效。并且,我们在CI中使用Unity的headless模式,无法实现这一特点。
自定义assembly
https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html
assembly 程序集,是一个包含编译过的c#代码和程序集依赖关系的代码库。自定义assembly可以增强代码模块化和重用性,
创建一个assembly
使用 Assets/Create/Assembly Definition在文件夹下创建一个asset,Unity会根据其设置,把该文件夹下所有代码编译到这个assembly中。包含其内部的子文件夹,除非子文件夹下也定义了assembly definition asset。
如果想要把其他文件夹下的内容也包含到某一个assembly当中,需要在该文件夹内定义一个assembly definition reference,并且设置reference的assembly。
引用和依赖
当一个类使用到另外一个类,就表示它依赖于另外一个类。如果两个类型在不同的assembly当中,那么第一个类的assembly需要引用另外的assembly。
默认情况下,预定义的assembly会自动引用自定义assembly和预编译assembly(Plugins)。可以通过关闭Auto Referenced选项,取消自动引用。关闭以后,自定义assembly的修改不会引发预定义assembly的重新编译,同时预定义assembly中的代码不能访问自定义assembly中的内容。需要跟进情况斟酌。
疑问:这里的.asmdef不能访问Assembly-CSharp中的内容,但是它可以访问所有的Unity程序集代码、Packages中的代码,文档中没有详细说明,它们是属于Precompiled Assemblies吗?
仔细看asmdef的内容,发现程序集默认依赖了引擎的程序集,No Engine References可以取消引用;另外Packages中的访问,也必须定义引用才行,使用Assembly Definition References进行设置。
循环引用
不同程序集之间不允许循环引用,如果发生了会报错。
其他
assembly definition asset还有很多其他的设置项,跟进情况查看文档使用。