版本:Unity 6 (6000.0)
语言:英语
包清单
程序集定义和包

版本控制

包必须遵循语义版本控制 (SemVer)。语义版本控制是一种策略,允许包作者提供有关给定版本中包含的更改类型(与先前版本相比)的信息,并以自动化工具可以使用的格式提供。

语义版本控制将版本表示为MAJOR.MINOR.PATCH,其中 MAJOR 引入了一个或多个重大更改,MINOR 引入了一个或多个向后兼容的 API 更改,而 PATCH 仅引入错误修复,没有任何 API 更改。

当您开始开发包时,将版本号从0.1.0开始。MAJOR 版本号0保留给处于初始开发阶段的包。在初始开发期间,包 API 经常发生更改,并且经常以重大方式发生更改,因此请将 MAJOR 版本号保持在0,直到您认为您的包足够稳定并准备好用于生产环境。

在包正式准备好用于生产环境后,将 MAJOR 版本递增至1,并遵循以下准则进行后续更改

递增此值 在以下条件下 示例
MAJOR 至少存在一个重大更改,并且两个版本的包都不能相互替换。重大更改包括

• 以可能导致编译或运行时错误的方式更改 API 表面(API 的公开部分)或功能。
• 删除非 API 功能,包括删除资源或更改资源的 GUID。
• 删除或重命名程序集和资源(因为编译器可能无法找到它们)。

注意:递增主要版本时,始终将PATCHMINOR值重置为0
版本 1.2.3 和 2.0.0 不兼容,不能互换使用,否则存在风险。
MINOR
(相同的MAJOR值)
最高的MINOR以向后兼容的方式引入功能。向后兼容(或非重大)API 更改包括

• 更改 API 表面或功能,而不会导致编译或运行时错误。
• 添加非 API 功能。
• 添加程序集和资源(因为新项目没有预先存在的引用)。

注意:递增次要版本时,始终将PATCH版本重置为0
您可以使用版本 1.3.0 来满足对 1.2.0 的依赖关系,因为 1.3.0 是向后兼容的。

您不能使用 1.2.0 来满足对 1.3.0 的依赖关系。
PATCH
(相同的MAJOR.MINOR值)
最高的PATCH以向后兼容的方式引入错误修复,而无需更改 API。如果 API 没有更改,则表示

• API 表面相同,功能保持不变。
• 更改不会改变公共 API。
版本 1.3.0 和 1.3.1 应该是可以互换的,因为它们具有相同的 API,即使 1.3.1 包含 1.3.0 中不存在的错误修复。

遵循这些版本控制实践允许包管理器自动解决冲突(如果可能),或将包升级到更新的、向后兼容的版本。

以下部分描述了一些场景,以帮助您确定这些规则如何影响各种包元素

除了这些场景之外,还有另一个因素可能会影响某些更改,这些更改通常只需要增加 MINOR 或 PATCH 版本:自动引用属性是启用还是禁用。

自动引用

您可以为程序集定义设置的属性之一是自动引用属性,该属性控制 Unity 在编译期间是否自动引用该文件。启用此属性时,某些通常只需要增加 MINOR 或 PATCH 版本的更改现在将成为重大更改。

当您禁用自动引用时,如果您进行任何导致新的程序集可用的更改,则您正在对 API 引入向后兼容的更改。向后兼容的 API 更改,例如添加平台禁用 Unity 测试引用添加新的.asmdef删除定义约束,只需要MINOR递增。

但是,当您启用自动引用时,该新添加的程序集将隐式添加到各种其他程序集的引用中。由于这些情况可能导致这些其他程序集中出现编译错误,因此需要MAJOR递增。

另一种常见情况发生在您添加或更改包依赖项的版本时。大多数情况下,更改包依赖项只需要PATCH递增。但是,新包版本可能包含一个具有自动引用属性启用的程序集,这将成为重大更改,因此需要MAJOR递增。

为了避免此类问题,始终尝试避免将第三方 DLL 文件放入不相关的包中(例如,在 SaveGameManager 包中包含Newtonsoft.Json.dll)。

资源

项目可以引用资源数据库中可见的任何资源。资源数据库使用其.meta文件中定义的 GUID 唯一地跟踪这些资源。

当您对公共 API 引入以下更改之一时,这需要一个新的MAJOR版本,因为它们是重大更改

场景 为什么这些是重大更改
删除资源数据库中可见的资源 如果您删除资源,这可能会破坏用户项目或其他包中的引用。
更改资源的 GUID 如果更改资源 GUID,资源数据库会将其理解为删除原始资源,然后添加一个新的(相同)资源。这会导致引用断开,因为原始 GUID 不再指向资源,因此资源数据库无法解析引用。

程序集

程序集定义.asmdef)定义一组脚本一段代码,允许您创建自己的组件、触发游戏事件、随时间推移修改组件属性并以任何您喜欢的方式响应用户输入。 更多信息
参见术语表
,Unity 编辑器的编译管道将其转换为单独的托管程序集(.dll)。这些.asmdef资源包含驱动生成的程序集属性的属性。这包括

  • 导入设置,例如包含和排除的平台
  • 与编译相关的属性,例如输出程序集名称和提供给编译器的引用以构建程序集。

大多数属性都会影响程序集的使用者,因此更改任何这些属性都构成对包的公共 API 的更改。其他属性对程序集的使用者没有影响,因此更改任何这些属性都不被视为更改包 API。

警告自动引用属性是一个特殊情况,因为许多通常根本不会更改 API以向后兼容的方式更改 API的更改可能会导致编译错误,具体取决于它是否已启用。有关更多信息,请参阅自动引用

Unity 可以预编译程序集,也可以从脚本和程序集定义编译程序集。因此,适用于程序集定义的任何内容通常也适用于预编译程序集。

本节详细介绍了程序集定义和预编译程序集中的更改,以及对包版本的影响

仅限 MAJOR:重大更改

当您对公共 API 引入重大更改时,这需要一个新的MAJOR版本,因为它可能会导致编译和运行时错误。这些场景都会从任何其他引用它的程序集中删除或隐藏程序集。当使用在引用的程序集中定义的类型的程序集被编译时,如果编译器找不到该程序集,则会导致编译错误。有关使用程序集和程序集定义的更多信息,请参阅程序集定义

请注意,以下内容适用于包使用和使用的运行时和编辑器程序集。它不适用于测试程序集,因为包通常不会使用它们,因此它们不是包 API 的一部分。

场景 编译器找不到引用的程序集的原因
删除程序集定义或预编译程序集 删除程序集定义文件会阻止编译管道生成相应的程序集。

注意:从 2019.1 开始,允许缺少引用以支持“可选引用”用例,但重命名 Unity 需要编译程序集定义的程序集会导致编译错误。同样,如果已编译的代码需要来自程序集的类型,则重命名该程序集会导致运行时错误,例如TypeLoadException
更改程序集名称(在.asmdef文件中或重命名.dll文件) 更改程序集名称等效于删除程序集,然后添加一个具有不同名称的新程序集。这意味着 Unity 将原始程序集视为丢失,即使 API 在另一个名称下仍然包含相同的程序集代码。
.asmdef添加定义约束 如果您添加定义约束,则只要不满足定义约束,Unity 就会跳过编译程序集。这会创建程序集丢失的情况,即使它之前可用。
删除平台 如果您删除对特定平台的支持,则 Unity 将不再在该平台上导入程序集,这等效于删除程序集。

您可以通过启用以下属性之一来删除平台
includePlatforms,这会破坏与所有未列出的平台的兼容性
excludePlatforms,这会向其中添加条目
将公共 API 从一个程序集移动到另一个程序集 当您将可公开访问的代码从程序集 A 移动到程序集 B 时,任何引用 A 但不引用 B 的程序集都无法编译。

对于程序集定义,如果您四处移动脚本,则可能正在将公共 API 移动到不同的程序集。
更改自动引用属性 当您禁用自动引用属性时,您将无法在没有显式引用的情况下使用此程序集的公共 API



• 对于预编译程序集,禁用此属性可阻止 Unity 将预编译程序集隐式添加为程序集定义和项目编译程序集的引用。
• 对于程序集定义,禁用此属性可阻止 Unity 将生成的程序集隐式添加为项目编译程序集的引用。

当您启用**自动引用**属性时,可能会导致与对 API、属性或依赖项的其他更改发生冲突。有关更多信息,请参阅自动引用部分。
在程序集定义中启用**Unity 引用 → 测试程序集**属性 启用**Unity 引用 → 测试程序集**属性会将此程序集标记为测试程序集,并且 Unity 通常不会将其包含在构建中(或在某些情况下编译它)。发生这种情况时,任何引用丢失程序集的程序集都无法找到它,除非它也是测试程序集。

主要版本、次要版本:非破坏性 API 更改

以下更改是向后兼容的,或非破坏性的 API 更改。这些场景都会添加一个程序集,这与删除程序集的破坏性更改不同。由于添加程序集会增加 API 表面(API 的公开部分),因此它被认为是 API 更改。但是,不存在现有引用,因此添加新程序集不会影响使用早期 API 创建的其他程序集。

向后兼容的更改至少需要一个新的次要版本。如果您包含其他破坏性更改的更新,则这些更改也可以是新的主要版本的一部分。

警告:仅当禁用**自动引用**属性时,这些更改才向后兼容。当启用**自动引用**属性时,此表中列出的更改可能会导致破坏性更改。有关更多信息,请参阅自动引用部分。

场景 为什么这些更改不会破坏编译
从 .asmdef 中删除定义约束 删除定义约束意味着编译和脚本管道不再跳过此程序集。因为 Unity 始终构建该程序集,所以编译器始终可以解析对它的引用,而不管是否满足该定义约束。
添加平台 添加平台不会影响现有的平台支持,因此它是向后兼容的。这是一种 API 更改,因为它增加了 API 表面。

您可以通过修改以下属性来添加平台
• 向**includePlatforms**属性添加条目。
• 完全删除**includePlatforms**属性。这等效于添加尚未在**includePlatforms**属性中的所有平台。
• 从**excludePlatforms**属性中删除条目。
使用新脚本创建程序集定义(以前不在不同的.asmdef文件中) 添加新的程序集会增加 API 表面(API 的公开部分),而不会更改任何现有实现。
在程序集定义文件中禁用**Unity 引用 → 测试程序集**属性 禁用**Unity 引用 → 测试程序集**属性会将此程序集标记为常规程序集,因此 Unity 不再将其与任何程序集定义区别对待。这是一种 API 更改,因为它增加了 API 表面。

主要版本、次要版本、修补版本:无 API 更改

以下更改不会影响公共 API,并且允许在修补版本中进行。这些场景中的更改不会更改公共 API,因为它们不会影响 API 表面(API 的公开部分),也不会更改其他用户的任何内容。

不更改公共 API 的更改至少需要一个新的修补版本。如果您包含其他引入破坏性更改或非破坏性更改的更新,则您也可以将它们包含在主要版本次要版本中。

场景 为什么这些更改不会影响其他用户
更改.asmdef文件中引用的程序集和程序集定义的列表 引用另一个程序集的程序集不会自动引用该另一个程序集自己的引用,而必须显式列出它们。因此,更改程序集定义或程序集中的引用不会影响其他用户。
更改程序集定义中的**允许不安全代码**属性 此属性控制编译器是否允许编译具有**不安全**修饰符的代码。仅更改该标志不会更改公共 API。
更改程序集定义中的**覆盖引用**属性 此属性控制 Unity 如何为该程序集调用编译器,并且对生成的程序集的用户没有影响。仅更改该标志不会更改公共 API。

包清单文件

包清单每个包都有一个清单,它向包管理器提供有关包的信息。清单包含诸如包的名称、版本、用户描述、对其他包的依赖项(如果有)以及其他详细信息等信息。 更多信息
参见词汇表
文件 (package.json) 指定包本身的名称、版本、包依赖项和其他元数据。

本节详细介绍了包清单文件中的更改以及对包版本的影响

名称更改(不允许)

更改**名称**属性等效于删除一个包并添加一个具有不同名称的新包,并且不支持。您不能通过尝试发布更新来重命名包:您必须将其作为全新的包发布。不允许更改名称,因为现有项目和包无法将名称解释为同义词。

依赖项更改

更改项目中的依赖项本身不需要不同的主要版本或次要版本,除非它是 API 更改的一部分或启用了自动引用属性。

本节提供了依赖项更改的示例以及它们适用的上下文(假设自动引用属性已禁用并且除了每个案例所描述的内容之外没有其他 API 更改)

依赖项更改 上下文 最小版本更改
添加新的依赖项 • 使用新包而不更改功能行为,并且不更改 API 表面。 PATCH
• 使用新包引入新行为,而不修改 API 表面。
• 创建公开新包中定义的类型的新的 API。
MINOR
• 使用新包以不向后兼容的方式更改现有行为,而不修改 API 表面。
• 以不向后兼容的方式修改现有 API 以公开新包中定义的类型。
MAJOR
删除依赖项 • 删除包而不更改功能行为,并且不更改 API 表面。 PATCH
• 删除包会导致以不向后兼容的方式更改现有行为,而不更改 API 表面。
• 删除公开该依赖项中定义的类型的 API。
MAJOR
更改依赖项 • 使用修改后的包而不更改功能行为,并且不更改 API 表面。 PATCH
• 使用修改后的包引入新行为,而不修改 API 表面。
• 创建公开修改后的包中定义的类型的新的 API。
MINOR
• 使用修改后的包以不向后兼容的方式更改现有行为,而不修改 API 表面。
• 以不向后兼容的方式更改现有 API 以公开修改后的包中定义的类型。
• 公开 API 中的一些类型,这些类型在修改后的包中以不向后兼容的方式进行了更改。
• 公开 API 中的一些类型,这些类型在修改后的包中不再定义。
MAJOR

主要版本、次要版本或修补版本:其他更改

您可以在任何发行版本中更改对包管理器、构建管道、脚本管道或资源数据库没有特殊影响的包清单属性。这包括更改**描述**、**类别**、**关键字**或**显示名称**。

如果您更改了这些字段,这可能表明您的更改不仅仅涉及错误修复。始终考虑新版本中的其他更改是否实际上需要新的次要版本或主要版本而不是修补版本。

注意:包清单中**unity**或**unityRelease**属性的更改始终需要次要版本或主要版本。尽管这些属性本身不会影响包 API,但增加 Unity 版本会排除包版本在以前的 Unity 编辑器上运行的可能性,并可能破坏依赖项项目或包。降低 Unity 版本使包可用于较旧的 Unity 编辑器。

已弃用和过时的 API

当您想从 API 中删除某些功能时,首先发布至少一个包含弃用信息的次要版本。这会警告用户即将删除的功能,以便他们可以顺利过渡到新的 API。然后,您可以在新的主要版本中删除该功能。

如果另一个开发人员使用警告标记包已过时,并且您在项目中启用了**警告视为错误**,则过时的包在技术上可能会破坏您的项目,即使它不是真正的破坏,因为代码仍然像以前一样工作。

在这种情况下,您可以选择如何修复警告作为错误(按典型期望的顺序递减)

  • 更改您的代码,以便您不再使用 API。
  • 将使用 API 的代码包装在#pragma warning指令中以消除警告。
  • 禁用警告CS0612(已弃用)CS0618(带有消息的已弃用)
  • 在您的项目中禁用**警告视为错误**。
包清单
程序集定义和包