请选择 进入手机版 | 继续访问电脑版

查看: 2111|回复: 1

[原创] Unity 2017.3 新功能:程序集定义文件

[复制链接]

1010

主题

1692

帖子

2万

贡献

管理员

Rank: 9Rank: 9Rank: 9

积分
21930
QQ
发表于 2017-11-30 02:03:24 | 显示全部楼层 |阅读模式
我们已经为大家介绍过Unity 2017.3中粒子系统改进以及Crunch纹理压缩库。今天我们将为大家介绍Unity 2017.3中的新功能:程序集定义文件Assembly Definition File。

6.jpg


程序集定义文件Assembly Definition File,使用该特性,开发者可以在一个文件夹中自定义托管程序集。定义明晰的依赖文件,可以确保脚本被更改后,只会重新生成必需的程序集,减少编译时间。

开发者的项目越大,编译时间必然会越长。而在进行项目迭代时,这很容易会成为一个问题,因此设置好正确的程序集定义文件可以助力提高工作效率,减少等待脚本编译的时间。

脚本编译—程序集定义文件


Unity自动定义脚本编译为托管程序集的方式。Unity编辑器中进行脚本更改迭代的编译时间会随脚本数量的增加而增加。当然, 在进行迭代时,我们一定是希望编译的速度越快越平顺越好。

你可以使用新的程序集定义文件特性,基于文件夹中的脚本定义你自己的托管程序集。如果你将项目脚本分为多个程序集,并进行良好的依赖定义,可以确保你在更改某个脚本时,只会重新生成必需的程序集。这减少了编译时间,因此你可以在Unity项目中将每个托管程序集看做是单个的库。

1.png
(图 01)


图01展示的是可以将项目脚本分为多个程序集。如果你仅仅更改了Main.dll中的脚本,那其它程序集都不需要重新编译。由于Main.dll包含的脚本更少,因此它的编译速度比Assembly-CSharp.dll更快。 同样的,你对Stuff.dll的更改,仅会导致Main.dll和Stuff.dll重新编译。

如何使用程序集定义文件

程序集定义文件是资源文件,可以通过Assets > Create > Assembly Definition菜单创建。它们的扩展名是.asmdef

你可以将一个程序集定义文件添加到Unity项目中的一个文件夹里,对该文件夹里所有的脚本进行编译,然后在检视窗口中对程序集名称进行设置。

注意:程序集定义文件所在的文件夹名称,以及程序集定义文件的文件名,对程序集的名称毫无影响。

2.png
(图 02)


你还可以使用检视窗口添加对项目中其它程序集定义文件的引用。编译程序集和定义程序集间的依赖时会用到这些引用。

Unity使用引用来编译程序集,以及定义程序集之间的依赖关系。你可以在检视窗口中设置程序集定义文件的平台兼容性,也可以选择排除或包括特定平台。

文件夹层级中的多程序集定义文件

如果在一个文件夹层级中,有多个程序集定义文件(扩展名:asmdef),将会使每个脚本被添加到最短路径距离的程序集定义文件中去。

示例


假设你有一个Assets/ExampleFolder/MyLibrary.asmdef和一个Assets/ExampleFolder/ExampleFolder2/Utility.asmdef文件,那么:
  • Assets > ExampleFolder > ExampleFolder2文件夹中的所有脚本将会被编译到Assets/ExampleFolder/ExampleFolder2/Utility.asmdef定义的程序集中。

  • Assets > ExampleFolder文件夹中的所有脚本,除Assets > ExampleFolder> ExampleFolder2中的脚本之外,将会被编译到Assets/ExampleFolder/MyLibrary.asmdef定义的程序集中。


程序集定义文件不属于生成系统的文件

注意:程序集定义文件不属于程序集生成文件。它们不支持在生成系统中常见的条件化生成规则。

这也是程序集定义文件不支持预处理指令(定义)的原因,因为它们一直是静态的。

向后兼容与隐式依赖

程序集定义文件向后兼容Unity中现存的[预定义编译系统](Predefined Compilation System)。也就是说,预定义程序集总是依赖于每个程序集定义文件的程序集。这与Unity中所有脚本都依赖于所有和当前生成目标兼容的预编译程序集(插件/.dll)的情况相似。

3.png
(图 03)


图3中的图表展示了预定义程序集、程序集定义文件以及预编译程序集之间的依赖关系。

Unity给予程序集定义文件的优先级要比[预定义编译系统](ScriptCompileOrderFolders)高。

这意味着,任何来自程序集定义文件文件夹内的预定义编译的特殊文件夹名,都不会对编译产生任何影响。Unity只将它们视为常规文件夹。

强烈建议你对项目中的所有脚本使用程序集定义文件,或完全不使用。否则,没有使用程序集定义文件的脚本会在每次程序集定义文件重新编译时也被重新编译。这会减少你在项目中程序集定义文件所带来的好处。

API

在UnityEditor.Compilation命名空间中,有一个静态的CompilationPipeline类,你可用它获取程序集定义文件以及所有由Unity生成的程序集的信息。

文件格式

程序集定义文件都是JSON文件。它们有以下这些字段:

4.jpg


字段includePlatformsexcludePlatforms不能在同一个程序集定义文件中使用。要获取平台名,可使用:

CompilationPipeline.GetAssemblyDefinitionPlatforms

示例

[C#] 纯文本查看 复制代码
MyLibrary.asmdef
{
"name" : "MyLibrary" ,
"references" : [ "Utility" ],
"includePlatforms" : [ "Android" , "iOS" ]
}


[C#] 纯文本查看 复制代码
{
"name" : "MyLibrary2" ,
"references" : [ "Utility" ],
"excludePlatforms" : [ "WebGL" ]
}


相关资源

  • Unity 2017.3 Beta版:

https://unity3d.com/unity/beta

  • Assembly Definition Files:

https://oc.unity3d.com/index.php/s/xIUxflUSkbcipM8

小结

在等待Unity 2017.3正式发布之前,你可以马上测试这些特性。记得在升级你的项目先做备份。我们会为大家分享更多Unity 2017.3的新功能,请注意关注Unity官方社区(Unitychina.cn) !

2

主题

17

帖子

585

贡献

中级UU族—1级

Rank: 4

积分
585
发表于 2017-11-30 08:40:22 | 显示全部楼层
两个问题:
1、在2017.3.0b11上创建了Main、UI、Lib三个程序集定义文件,分别位于Assets/_Script/Main,Assets/_Script/UI,Assets/_Script/Lib三个文件夹内。设置Main依赖于Lib。生成的文件内容如下:
{
    "name": "Main",
    "references": [
        "Lib"
    ],
    "includePlatforms": [],
    "excludePlatforms": []
}

这个和文中的【字段includePlatforms和excludePlatforms不能在同一个程序集定义文件中使用】不符,是否需要手动删除?
2、同时设置好UI依赖Lib。然后在上述的三个文件夹内创建一些空的脚本,此后试图用VS2015打开编辑脚本,报错如下:

ArgumentException: Value does not fall within the expected range.
SyntaxTree.VisualStudio.Unity.Bridge.CompilationUnit.LanguageOf (SyntaxTree.VisualStudio.Unity.Bridge.CompilationUnit unit)
SyntaxTree.VisualStudio.Unity.Bridge.CompilationUnit.CompilationUnits ()
SyntaxTree.VisualStudio.Unity.Bridge.ProjectSystem.UnitySolutionBuilder..ctor ()
SyntaxTree.VisualStudio.Unity.Bridge.ProjectSystem.UnitySolutionBuilder.CreateSolutionFromAssetDatabase ()
SyntaxTree.VisualStudio.Unity.Bridge.ProjectFilesGenerator.GenerateProject ()
SyntaxTree.VisualStudio.Unity.Bridge.ProjectFilePostprocessor.OnPreGeneratingCSProjectFiles ()
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115)
UnityEditor.AssetPostprocessingInternal.OnPreGeneratingCSProjectFiles () (at C:/buildslave/unity/build/Editor/Mono/AssetPostprocessor.cs:61)
UnityEditor.VisualStudioIntegration.SolutionSynchronizer.Sync () (at C:/buildslave/unity/build/Editor/Mono/VisualStudioIntegration/SolutionSynchronizer.cs:186)
UnityEditor.SyncVS.SyncSolution () (at C:/buildslave/unity/build/Editor/Mono/SyncProject.cs:192)
UnityEditor.SyncVS.SyncAndOpenSolution () (at C:/buildslave/unity/build/Editor/Mono/SyncProject.cs:183)


请问这个是啥情况,需要2017?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表