找回密码
 立即注册
查看: 269|回复: 0

Unity的程序集剖析

[复制链接]
发表于 2022-8-13 16:10 | 显示全部楼层 |阅读模式
作者:如山如风
程序集的概念

程序集是Unity的脚本代码进行编译的一个逻辑单元,把相关的代码和资源文件进行组合,然后生成可执行文件.exe或者类库文件.dll。
由于程序集在编译后并不一定会生成单个文件,而可能会生成多个物理文件,甚至可能会生成分布在不同位置的多个物理文件,所以程序集是一个逻辑单元,而不是一个物理单元。即程序集在逻辑上是一个编译单元,但在物理储存上可以有多种存在形式。
对于静态程序集可以生成单个或多个文件,而动态程序集是存在于内存中的。
在Unity脚本编程中程序集处处可见,因为任何基于.NET的代码在编译时都至少存在一个程序集(所有.NET项目都会默认引用mscorlib程序集)。
程序集包含:

  • 资源文件
  • 类型元数据(描述在代码中定义的每一类型和成员,二进制形式)
  • IL代码(这些都被封装在exe或dll中)
程序集包括两种常见的格式,即exe与dll,它们的区别是exe可以运行,dll不能直接运行,因为exe中有一个main函数(入口函数)。
程序集的优点

在项目开发中,程序集的使用较多,主要有以下几个优点:

  • 通过定义程序集,可以组织代码以促进模块化和可重用性。
  • 开发者可以自定义程序集,定义明晰的依赖关系,可以让脚本修改后只会重新生成必需的程序集,而不用全项目重新编译,减少编译时间。
  • 支持跨语言的编程,例如可以在Unity中使用C++语言编辑的DLL文件。
我们以Assembly-CSharp.dll这个常用的.Net程序集来举例说明,它的结构如下图所示:


上图演示了如何将项目中的代码拆分为多个程序集,即:

  • Main 引用 Stuff 并且不进行反向引用,所以知道对 Main 中的代码进行的任何更改都不会影响 Stuff 中的代码。
  • Library 不依赖于任何其他程序集,所以可以更轻松地在其他项目中重用 Library 中的代码。
程序集的定义

通过使用程序集定义,可以将Unity项目中的脚本组织到程序集内。
要将项目代码组织成程序集,请为每个所需程序集创建一个文件夹,并将应属于每个程序集的脚本移动到相关文件夹中,然后用Unity IDE中的[创建程序集定义资源]功能指定程序集属性。
程序集定义资源,它是一个文本文件,文件扩展名为 .asmdef,其中包含定义程序集定义属性的 JSON 字符串。
在文件夹中创建一个程序集定义资源后,Unity会从该文件夹中的所有脚本编译一个单独的托管程序集。除非子文件夹有自己的程序集定义,否则将包含子文件夹中的脚本。这些托管程序集充当 Unity 项目中的单个库。
比如,我们想将某个名为TEST的文件夹打包成程序集,就可以用Unity IDE打开这个工程,然后在TEST文件夹根目录下创建一个名为AssemblyDefinitionFile.asmdef文件,它的内容是一个 JSON 格式的字段,创建之后,就可以使用外部编辑器来直接编辑 JSON,如下图所示:


编辑完成AssemblyDefinitionFile.asmdef文件之后,直接用Unity IDE编译工程,编译完成之后,就会在工程的Library/ScriptAssemblies文件夹下生成对应名字的程序集。
asmdef文件说明

扩展名为asmdef的文件,即程序集定义文件,它是Assembly Definition的缩写,在Unity中,此扩展名的文件专门用来定义程序集。
创建方法

通过 Assets > Create > Assembly Definition菜单来创建,文件扩展名为.asmdef,我们称之为ADF文件。
ADF文件会把其所在文件夹下的脚本打入同一个程序集中。
多层级ADF

如果一个文件夹及子文件夹中,有多个ADF,每个脚本被添加到离这个脚本最短路径的ADF中去。
如果搞不清楚一个脚本究竟被包含在了哪个ADF中,只需要选中这个脚本,在Unity IDE的Inspector面板中就会清楚的看到。
示例说明

在 Unity 中,程序集定义文件等效于 .NET 生态系统中的 C# 项目。必须在程序集定义文件中设置对其他程序集(无论是在同一包中还是在外部包中)的显式引用。
在此示例中,程序集定义文件使用对其自身程序集以及作为包依赖项的一部分的程序集的引用。
{
    "name": "Example.TEST.Sample",
    "references": [
        "Example.Framework.Tools",
        "Example.Framework.Utils"
    ],
    "includePlatforms": [],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "overrideReferences": false,
    "precompiledReferences": [],
    "autoReferenced": true,
    "defineConstraints": [],
    "versionDefines": [
        {
            "name": "com.example.test.sample1",
            "expression": "1.0.0",
            "define": "EXAMPLE_SAMPLE_ONE"
        },
        {
            "name": "com.example.test.sample2",
            "expression": "1.0.1",
            "define": "EXAMPLE_SAMPLE_TWO"
        }
    ],
    "noEngineReferences": false
}程序集的使用

在Unity中,程序集的使用是非常简便的。
如果我们要使用第三方的程序集,如果它是全平台通用的,那么只需要将它拷贝到Assets/Plugins文件夹下就可以在代码中直接引用它所包含的类,至于程序集的自动关联和编译工作就交给Unity IDE来负责,不需要用户手动操作。
但这里还需要注意一点,一些Android专用的程序集需要拷贝到Assets/Plugins/Android文件夹下,iOS专用的拷贝到Assets/Plugins/iOS文件夹下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-18 17:24 , Processed in 0.098416 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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