程序集定义(Assembly Definition File)

程序集定义(Assembly Definition File),第1张

Unity开发者可以在一个文件夹中自定义程序集。定义明晰的依赖关系,可以确保脚本更改后,只会重新生成必需的程序集,减少编译时间。

在一个项目中会存在多个程序集,例如SDK集合、热更集合、插件集合、主集合等,如果未自定义程序集,修改其中一个集合的脚本后Unity再次编译,这时Unity会将所有集合都编译一遍,时间的浪费是我们所不希望的。当我们为每一个集合都定义程序集后,修改脚本只会编译对应的程序集。

通过在Unity中点击:Assets >Create >Assembly Definition菜单创建。该文件的扩展名是.asmdef。

需要注意的是程序集名与文件名无关,真正有关联关系的是Inspector面板中Name对应的名称

该程序集我们还可以在解决方案中观察到

程序集依赖关系成树状,一旦确立依赖关系,低层级的程序集则无法调用高层级程序集里的类和方法。

这里我设立了三个程序集:Unity.Hotfix、Unity.Model、Unity.ThirdParty;

他们之间的依赖关系如下

这样在Hotfix程序集里可以调用Model与ThirdParty程序集中的脚本,但是Model无法调用Hotfix程序集中的脚本

程序集会管理它当前所在文件夹和子文件夹中的脚本。

如果一个脚本当前文件夹中定义了一个程序集,它的父文件夹中也定义了一个程序集,该脚本会被归纳到它当前文件夹的程序集中

在平台中可以设置程序集编译平台

这样可以使某些程序集避免在一些特殊平台下被编译,常见的例如我们希望我们的Edtor程序集或热更资源程序集只在编辑器下被编译,那么我们就可以在平台设置中只勾选Editor

1.为了搞清楚缩小很慢我这里使用Unity2021LTS版本新建个项目。

GIF

2.这个时候Unity会自动打开我们刚创建的项目,我们直接去资源管理器里面查看一下Unity都为我们创建了哪些文件。

GIF

这个时候,我们重点关注一下Library文件夹,俗称的库文件。

3.打开Library文件夹,我们可以看到一个名为脚本程序集的文件夹ScriptAssemblies,这里是存放我们代码、程序集的地方。映入眼帘的是一堆dll和pdb文件:

这个时候你可能会有疑问了,我一个空的项目会什么会有这么多程序集?

想要搞明白这点,我们需要先了解一下Unity包中的清单,也叫项目清单。

项目清单

这是官方对项目清单的解释:Unity 加载项目时,Unity Package Manager 会读取项目清单,以便计算要获取并加载的包的列表。

猜想1:这个会不会是导致Unity变慢的原因呢?我们该如何验证这点呢?

打开manifest.json文件,映入我们眼帘的是一堆依赖项。如果我们将所有的依赖项全部删除会发生呢?

下面是删除之后的样子:

回到Unity,首先Unity会删除上文中提到的ScriptAssemblies文件夹,然后重新编译整个项目。这个时候我们再打开ScriptAssemblies查看一下文件夹的内容,你会发现,所有的dll和pdb文件都消失了,变成了一个空文件夹。

这个时候,我们不仅验证了我们的猜想1,还得出一个结论:没有依赖项,就没有程序集。单有这点我觉得还不够,接下来我们继续!

再次回到Unity,我们创建个HelloWorld脚本。这个时候Unity会自动为我们创建个Assembly-CSharp.dll。

GIF

查看一下ScriptAssemblies文件夹的变化,里面多了Assembly-CSharp.dll和Assembly-CSharp.pdb两个文件。这就说明我们新建的HelloWorld脚本已经被Unity构建和编译,这就是d出进度条的原因。

如果你觉得不可置信。那么我们可以将Assembly-CSharp.dll拖入dnSpy或者dotPeek中反编译查看一下里面的内容:

是不是觉得很酷?这不就是我们刚才新建的HelloWorld吗?这也就说明Assembly-CSharp.dll由HelloWorld.cs编译而成。

接下来删除HelloWorld.cs,伴随着读条结束,ScriptAssemblies文件夹会被再次清空。

构建属于自己的程序集

如果我们构建属于我们自己的程序集,而不是让Unity自动为我们生成Assembly-CSharp.dll,会大大提升编译速度和减少读条时间吗?

为了验证这点,我们新建Scripts ->My Assembly ->My Code.asmdef程序集,这个时候ScriptAssemblies文件夹还不会发生任何变化,因为这是个空的程序集,内部没有任何代码。我们只需要在My Code.asmdef同层级下创建个名为MyCode.cs的脚本即可

这个时候打开ScriptAssemblies文件夹我们会神奇的发现,这里出现的是我们自己的程序集,而不是Unity自动为我们生成Assembly-CSharp.dll。OHHHHHHHHHHHH....

猜想2:如果asmdef脚本没做任何变动,Unity会默认会跳过编译这部分代码吗?

我们可以再次验证一番,反正验证又不收钱。HAHAH~

我们在My Assembly文件夹同级目录再次创建HelloWorld.cs。注意创建位置,不要创建到My Assembly文件夹内部,那样就归属于My Code.asmdef的管辖范围了。后面有机会再和大家仔细的聊聊 asmdef,这里留个坑。如下图:

这个时候打开ScriptAssemblies文件夹我们会神奇的发现,Unity自动为我们生成了船新的Assembly-CSharp.dll,留意一下后面的修改日期。而MyCode.dll的修改日期是没有发生任何变化的,也就验证了猜想2Unity为我们跳过编译这部分代码结论是正确的。

那么我们把一些不常修改的代码,如底层框架和一些通用的拓展方法写到属于我们自己的程序集里面,那编译时间不久大大的减少了吗?你学废了吗?

总结

优化依赖项会大大提升我们的编译速度。

构建属于我们自己的程序集,而不是让Unity自动为我们生成Assembly-CSharp.dll也会大大提升编译速度和减少读条时间。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11396660.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-15
下一篇 2023-05-15

发表评论

登录后才能评论

评论列表(0条)

保存