概述

大概从 Unity 2017.3 开始,添加了 assembly definition 相关的功能。为了更深入的了解,进行了多次打包和对比。本文主要是对这一过程进行记录。

文档解释

1、编译脚本

Untiy 在默认情况下,根据脚本在项目中的文件夹,会分成四个阶段编译脚本。

当脚本引用在其它阶段 (即位于不同程序集中) 编译的类时,编译顺序非常重要。基本规则是,在当前编译阶段之后的任何编译阶段都不能被引用。在当前阶段或更早阶段编译的任何内容都是完全可用的。

编译的各个阶段如下:

阶段 程序集名 脚本文件
1 Assembly-CSharp-firstpass Standard Assets, Pro Standard Assets 和 Plugins 文件夹下面的运行时脚本
2 Assembly-CSharp-Editor-firstpass Standard Assets, Pro Standard Assets 和 Plugins 文件夹下面的 Editor 文件夹下面的 Editor 脚本
3 Assembly-CSharp 其它不在 Editor 文件夹下面的脚本
4 Assembly-CSharp-Editor 所有剩下的脚本(Editor 文件夹下面的脚本)

2、Assembly definitions

程序集是一个 C# 代码库,它包含由脚本定义的已编译类和结构,还定义了对其他程序集的引用。

默认情况下,Unity 将几乎所有的游戏脚本编译到预定义的程序集中(Assembly-CSharp.dll)。

这种安排对于小型项目来说是可以接受的,但是当你向项目中添加更多代码时,会有一些缺点:

  • 每当你改变一个脚本时,Unity 就必须重新编译所有其他脚本,这增加了迭代代码更改的整体编译时间。
  • 任何脚本都可以直接访问任何其他脚本中定义的类型,这使得重构和改进代码变得更加困难。
  • 所有脚本都是为所有平台编译的。

通过定义程序集,你可以组织代码以促进模块化和可重用性。你为项目定义的程序集中的脚本将不再添加到默认程序集中,并且只能访问你指定的其他程序集中的脚本。

上面的图表说明了如何将项目中的代码拆分为多个程序集。因为 Main 引用 Stuff 而不是相反,你知道任何对 Main 中的代码的更改都不会影响 Stuff 中的代码。类似地,因为 Library 不依赖于任何其他程序集,所以可以更容易地在另一个项目中重用 Library 中的代码。

默认情况下,预定义程序集引用所有其他程序集,包括使用 Assembly Definition(1) 创建的程序集和作为 plugin 添加到项目中的预编译程序集 (2)。此外,使用 Assembly Definition 创建的程序集自动引用所有预编译程序集 (3):

要将项目代码组织成程序集,请为每个所需程序集创建一个文件夹,并将应该属于每个程序集的脚本移动到相关文件夹中。然后创建 Assembly Definition 资产以指定程序集属性。

Unity 在一个包含 Assembly Definition 资产的文件夹中获取所有脚本,并使用该资产定义的名称和其他设置将它们编译为一个程序集。Unity 还将任意子文件夹中的脚本包含到同一程序集中,除非子文件夹有自己的 Assembly Definition 或 Assembly Definition Reference 资产。

要在现有程序集中包含来自非子文件夹的脚本,请在非子文件夹中创建 Assembly Definition Reference 资产,并将其设置为引用定义目标程序集的 Assembly Definition 资产。例如,你可以将项目中所有 Editor 文件夹中的脚本组合到它们自己的程序集中,而不管这些文件夹位于何处。

Assembly Definition Reference 在下面这种情况下可以解决问题:在 Unity 的 Packages 中,有一些访问级别为 internal 的类。如果我们在 Assets 下面创建脚本,是不能访问 Packages 中的 internal 类。有了 Assembly Definition Reference 就可以了。可以在创建的脚本的同级目录中创建一个 Assembly Definition Reference,设置引用包含 internal 类的 Package 即可。

一些实验

Unity 版本:2020.3.13f1

ILSpy 版本:7.1.0.6543

创建一个空的 URP 工程,设置到 Android 平台,Player Setting 中的 Scripting Backend 设置为 “Mono”。默认情况下,项目中包含的脚本如下所示:

每次打完包后,对 apk 进行解压即可。解压后,程序集的位置在 “{解压的文件}\assets\bin\Data\Managed\” 下面:

1、默认打包

我们需要关心的是 “Assembly-CSharp.dll” 程序集。使用 ILSpy 打开 Assembly-CSharp.dll,可以看到:

项目中的两个运行时脚本 Readme 和 SimpleCameraController 都被编译到程序集 Assembly-CSharp.dll 中。

2、使用 Assembly Definition

在 SimpleCameraController 的同级目标创建 Assembly Definition,Assembly Definition 的设置保持默认即可。观察 SimpleCameraController,可以发现 SimpleCameraController 的程序集信息是新创建的 Assembly Definition:

打包,解压,可以看到,刚才新创建的 Assembly Definition 产生的程序集:

使用 ILSpy 分别打开 Assembly-CSharp.dll 和 NewAssembly.dll,结果如下所示:

可以发现,SimpleCameraController 被编译进新的程序集 NewAssembly.dll 中,而原本的程序集 Assembly-CSharp.dll 中没有 SimpleCameraController 了。

3、使用 Assembly Definition Reference

删除上面创建的 Assembly Definition,在 SimpleCameraController 的同级目标创建 Assembly Definition Reference。假设,我们想访问的 Unity 的 Package 是 Unity UI,设置 Assembly Definition Reference 上的 Assembly Definition 为 UnityEngine.UI 即可,如下图所示:

打包,解压,可以看到,上面新创建的程序集 NewAssembly.dll 没了,而使用 ILSpy 打开 Assembly-CSharp.dll,也并没有看到 SimpleCameraController。那么,SimpleCameraController 去哪儿了呢?使用 ILSpy 打开 UnityEngine.UI.dll 程序集:

可以发现,SimpleCameraController 被包含到了 UnityEngine.UI.dll 程序集中,也就是说,SimpleCameraController 可以访问程序集中的 internal 级别的类了。

一些使用场景

  1. 对于 Assembly Definition 的用处,网上很多的介绍是可以加快代码编译速度。这个也很容易理解,使用 Assembly Definition 对项目中的脚本进行细分后,每次修改只需要编译脚本所在的程序集,因此减少了编译的时间。
  2. 如果想访问 Untiy 的 Package 中的 internal 类的话,由于可以获得 Package 的源码,当然可以直接在 Package 中添加修改。当现在如果不修改 Package 的话,就可以使用 Assembly Definition Reference,将自己的代码包含到 Package 中,这样,就会编译到同一个程序集中,也就可以访问 internal 类了。

参考

  • [1] Unity 2017.3
  • [2] Special folders and script compilation order
  • [3] Assembly definitions
  • [4] Unity3D 研究院新方法加快代码编译速度(九十六)
  • [5] 提升 Unity 编辑器中代码的编译速度

原文地址 zhuanlan.zhihu.com

Assembly definitions 的相关实验相关推荐

  1. 关于partnerLinkType的相关实验

    文章仅供大家参考,所有评论, 错误报告, 其他信息以及批评, 请邮寄到 Jeffery.Lee AT gmail.com 或者访问我的个人blog同我交流( http://ibuddie.spaces ...

  2. 小功率电子镇流荧光灯相关实验

    ➤01 小型电子荧光灯 在博文 小功率荧光灯拆解分析 中对于一款电子镇流器激励的小型荧光灯进行了相关实验.现在手边有一颗荧光灯,基于该荧光灯初步进行相关的电子实验. ▲ 已经拆开的荧光灯泡 荧光灯的主 ...

  3. tomcat相关实验

    tomcat相关实验 1.实现LNT 同主机实现 1.安装并启动tomcat 1)OpenJDK的安装yum install java-1.8.0-openjdk-devel.x86_64 确定JDK ...

  4. 秋水仙碱与牛血清白蛋白 (BSA)偶联物(相关实验)

    秋水仙碱与牛血清白蛋白 (BSA)偶联物(相关实验) 提供牛血清白蛋白BSA.鸡卵清白蛋白OVA.人血清蛋白HSA等蛋白偶联芍药苷.氟伐他汀.阿西美辛.利凡诺.氟尼辛.氨丙啉.卡托普利.阿米舒必利.金 ...

  5. STM32学习心得二十一:实时时钟RTC和备份寄存器BKP特征、原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容 1) RTC特征与原理: 2) BKP备份寄存器特征与原理: 3) RTC常用寄存器+库函数介绍: 4) 相关实验代码解读. 实验内容: 因为没有买LCD屏,所以计 ...

  6. STM32学习心得十八:通用定时器基本原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容: 1) 三种定时器分类及区别: 2) 通用定时器特点: 3) 通用定时器工作过程: 4) 实验一:定时器中断实验补充知识及部代码解读: 6) 实验二:定时器PWM输 ...

  7. 【评测】iPS细胞相关实验服务机构-魔法师的仓库

    由血液细胞重编程得到iPS细胞是一个经典实验,但由于实验周期长.涉及实验方法多.实验繁琐,对于没有受到过系统培训的人员,还是有一定难度的.现在,您可以选择我们的iPS细胞相关实验服务,节省您宝贵的时间 ...

  8. 计算机硬件检测标准模板,计算机硬件性能检测相关实验模板.doc

    文档介绍: 计算机硬件性能检测相关实验<计算机硬件性能检测>实验指导书实验目的:1.熟练掌握通过测试软件在不拆机情况下了解计算机硬件参数信息及性能检测方法;2.掌握常用CPU.内存.显卡. ...

  9. 频域波束形成matlab,SONAR_code 波束形成技术,包括相移 ,频域 matlab代码,以及相关实验的ppt 263万源代码下载- www.pudn.com...

    文件名称: SONAR_code下载  收藏√  [ 5  4  3  2  1 ] 开发工具: matlab 文件大小: 25848 KB 上传时间: 2015-05-03 下载次数: 21 提 供 ...

最新文章

  1. 1. CVPR2021-Papers-with-Code-Demo(CVPR2021论文下载)
  2. CentOS7编译安装MySQL5.7之后安装mysql-devel出错解决方案
  3. oracle数据库常用的99条查询语句
  4. go语言定义二维数组
  5. Eclipse公共许可证
  6. “睡服”面试官系列第十三篇之函数的扩展(建议收藏学习)
  7. finetune代码实战讲解(李沐)
  8. java 增 删 查 改_如何对java链表进行增、删、查、改操作
  9. getComputedStyle与currentStyle获取样式(style/class)
  10. Adobe Photoshop/Adobe Dreamwear/您此时无法使用此产品。您必须问题解决办法FLEXnet Licensing Service服务
  11. 10天学会c语言与单片机第6讲,10天学会单片机c语言视频
  12. PS动感映像插件ImageMotion 1.3中文汉化版
  13. 房屋租赁管理系统 基于SSM框架
  14. qq传离线文件提示服务器超时,QQ传文件时进度条显示不正常的解决办法
  15. AWS吹走了私有云天空中最后一片乌云
  16. Python 之霍兰德人格与职业分析
  17. 发那科机器人GI分配_发那科机器人应用-运动指令入门(1)
  18. 【教学类-30-04】10以内减法题不重复(一页两份)(包括6以内、7以内、8以内、9以内、10以内减法题 只抽取25个)
  19. 第2次作业:微信案例分析
  20. 几种最小二乘法及python代码:ELS、TLS、RLS

热门文章

  1. 【JavaWeb】HTML
  2. implicit declaration of function
  3. Windows 11/10/7离线安装.NET3.5
  4. 树莓派3b+刷openwrt固件,做无线路由。树莓派3b+做无线路由。
  5. Winform-TextBox实现 placeholder
  6. 动人的老磁带,蕴藏着俺的青春
  7. 电路原理习题(节点电流法,回路电流法)
  8. 何必心中无码,AI让你眼见为实
  9. 山科大图形学知识整理和2022考试回忆
  10. vue el-button v-if disable失效