文章目录

Unity’s Package Manager

包 (package) 是一种容器,用于存储各种类型的功能或资源,例如:

  • 编辑器工具和库:例如文本编辑器、动画查看器或测试框架。
  • 运行时工具和库:例如物理 API 或图形管线。
  • 资源集合:例如纹理或动画。
  • 项目模板:用于与他人共享常见的项目类型。

通过 Package Manager,包为 Unity 提供了广泛的增强功能。为了帮助查找和使用这些包,Package Manager 窗口提供了可以一起使用的包集合,称为功能集 (feature sets)。

在编辑器中,你可以通过以下菜单访问 Package Manager 窗口:Window > Package Manager

Package Manager 还支持管理从 Unity Asset Store 下载或导入的包。

Unity 提供了三种 Package Manager 接口:Package Manager window、Scripting API 和 manifest file 。下表包含了对每个接口的介绍及更多信息。

接口介绍
Package Manager 窗口在编辑器中通过菜单 Window > Package Manager 打开,用于浏览、安装、更新和移除包。
脚本 API (Scripting API)通过代码控制包的安装、更新和移除,适用于需要自动化管理包的高级用户。
Manifest 文件项目中的 manifest.json 文件,用于手动编辑包的依赖项和配置 scoped registries。

Unity 如何处理包

当 Unity 打开一个项目时,Unity Package Manager 会读取项目清单 (project manifest) (1),以确定要在项目中加载哪些包。然后,它会向包注册服务器 (package registry server) (3) 发送请求 (2),请求清单中列为依赖项的每个包。包注册服务器随后将请求的信息和数据发送回 Package Manager (4),然后 Package Manager 将这些包安装到项目中 (5)。每个项目都有自己的清单,其中列出了作为项目“依赖项”的包。

在这里插入图片描述

将包添加到项目需要更新项目清单,以确保 Package Manager 在依赖项列表中包含该包。尽管你可以直接修改项目清单,但使用 Package Manager 窗口更安全且更简单,因为它会为你管理项目清单的修改。

概念 (Concepts)

本节介绍有关 Unity Package Manager 功能的许多概念:

版本 (Versions)

每个包都有多个版本,标记了该包在自身生命周期中所经历的更改。每次开发人员更新包时,都会为该包提供一个新的版本号。包版本的更改会告诉你这次更改包含了重大更改(主要)、新的向后兼容功能(次要)还是仅 Bug 修复(补丁),并遵循语义版本控制 (Semantic Versioning)。

要查看特定包可用的版本列表,请参阅查找特定版本.

清单 (Manifests)

清单文件有两种类型:

  • 项目清单 (manifest.json):存储 Package Manager 在查找和加载正确的包时所需的信息,并列出声明为依赖项的包和版本。
  • 包清单 (package.json):存储有关特定包的信息,并列出该包所需的包和版本。

这两种文件都使用 JSON(JavaScript 对象表示法)语法。

注册表 (Registries)

在 Unity 的 Package Manager 的领域中,包注册表 (package registry) 是一个服务器,用于存储每个包版本的包内容和信息(元数据)。Unity 维护了一个可供分发的官方包的中央注册表。默认情况下,所有项目都使用官方的 Unity 包注册表,但是你可以添加其他注册表来存储和分发私有包或在开发期间暂存自定义包。

包管理 (Package Management)

Unity Package Manager 是管理整个包系统的工具。此工具的主要任务包括:

Unity Package Manager 按项目安装示例、工具和资源,而不是在特定机器或设备的所有项目中安装。它使用全局缓存(global cache)来存储下载的包元数据和内容。安装到项目中的包资产与项目中的其他资产一样处理,唯一的区别是这些资产存储在包文件夹(package folder)中且不可变。你只能从本地和嵌入式包来源永久更改内容。

包来源 (Package Sources)

来源描述了包的来源:

来源 (Source)描述 (Description)
注册表 (Registry)对于大多数的包,当你请求这些包时,Unity Package Manager 将它们从包注册表服务器下载到计算机上的全局缓存中。这些包是不可变的,因此你可以在项目中使用这些包,但不能修改这些包,也无法更改它们的包清单。
内置 (Built-in)这些包允许你启用或禁用 Unity 功能(例如,地形物理 (Terrain Physics)、动画 (Animation) 等)。这些包是不可变的。有关更多信息,请参阅内置包
嵌入式 (Embedded)项目文件夹中存储的所有包均为 embedded package 。此来源与 Custom state 相对应,因为当你开始自定义包的开发时,通常会将包所需的所有脚本、库、示例和其他资源放在项目文件夹下的文件夹中。
本地 (Local)可从计算机上的任何文件夹中安装包(例如,如果在本地克隆了开发代码仓库)。
Tarball (本地)可通过计算机上的 tarball 文件来安装包。Package Manager 从 tarball 中提取包并将其存储在缓存中。但是,与从本地文件夹安装不同,这些包是不可变的。
GitPackage Manager 直接从 Git 代码仓库安装基于 Git 的包,而不是从包注册表服务器进行安装。
要编辑包的包清单,请参阅检查包.

Package Manager 窗口显示与某些来源对应的标签。有关更多信息,请参阅标签

注意:Package Manager 将从 Asset Store 下载的包存储在一个与全局缓存分开的缓存中。有关更多信息,请参阅Asset Store 包

包类型 (Package Types)

Unity 的 Package Manager 支持两种包类型:

  • Unity Package Manager (UPM) 包
  • 资产包 (Asset packages),格式为 .unitypackage

下表比较了这些包类型的不同特征:

特征 (Characteristic)UPM 包 (UPM Packages)资产包 (Asset Packages)
格式 (Format)文件和文件夹的集合,可能根据分发方式进行压缩。带有 .unitypackage 扩展名的压缩文件
包的主要来源 (Primary source for the package)Unity 注册表、scoped 注册表或 Asset StoreAsset Store
是否使用包清单文件 (Uses a package manifest file)是 (Yes)否 (No)
将包添加到项目的方法 (Method for adding the package to a project)安装 (Install)下载并导入 (Download and import)
包添加到的项目文件夹 (Project folder the package is added to)Packages 文件夹Assets 文件夹
包添加到的缓存 (Cache the package is added to)全局缓存 (Global cache)资产包缓存 (Asset package cache)。请参阅下载的资产文件的位置.
是否可以手动从缓存中移除包 (You can manually remove the package from the cache)否 (No)是 (Yes)
详细信息面板中显示的标签集 (Sets of tabs that appear in the Details panel)描述 (Description)、版本历史 (Version History)、依赖项 (Dependencies)、示例 (Samples)(如果提供)、图像 (Images)(如果提供)概述 (Overview)、发布 (Releases)、导入的资产 (Imported Assets)、图像 (Images)
通过了解这些差异,你可以更好地管理和使用 Unity 项目中的包。

包状态和生命周期 (Package States and Lifecycle)

从 Unity 编辑器 2021.1 版本开始,一个包在其生命周期中可能会经历以下状态:
Unity Package Manager 的包生命周期

Package Manager 窗口显示与这些状态对应的标签。

注意:这些包状态仅适用于 Unity 内部开发的包。请联系第三方包开发者了解他们的具体流程。

依赖和解析 (Dependency and Resolution)

在 Package Manager 窗口中工作时,你可以从多个来源安装包(注册表,本地文件夹或者 tarball 以及 Git URL)。然而,尽管 Package Manager 可以无缝地从这些来源安装包,但它首先必须进行一系列计算,以决定安装哪个版本,以及安装哪些其他包和版本以支持它。

直接依赖 (Direct Dependencies)

当你通过 Package Manager 窗口选择要安装的包版本时,你正在向项目清单 (project manifest) 添加一个“依赖”。这表示你需要特定版本的某个包来使项目正常工作。要向项目添加依赖项,你需要在 <project-root>/Packages/manifest.json 文件的 dependencies 属性中添加对包和版本的引用,形式为 package-name@package-version。这些称为“直接”依赖,因为你的项目直接依赖于它们。

间接依赖 (Indirect Dependencies)

包也可以需要其他包才能正常工作。这些称为“间接” (indirect)(或传递性)依赖。包开发者在开发过程中将这些添加到包清单文件 (<package-root>/package.json) 的 dependencies 属性中。例如,在下图中,alembic@1.0.7 包依赖于 timeline@1.0.0 包,因此 timeline 包是一个“间接”依赖。另一方面,项目依赖于 cinemachine@2.6.0alembic@1.0.7 包,因此它们都是“直接”依赖。

直接和间接依赖

版本覆盖 (Version Overrides)

当你将一个包版本添加为依赖时,该版本不一定是 Package Manager 安装的版本,因为它必须考虑你项目中的所有依赖项,无论是直接的还是间接的。例如,在这种情况下,请求的 XR 插件管理包 (XR Plugin Management package) 版本是 4.0.3,但实际安装的版本是 4.0.6,因为另一个包依赖于更高版本,如信息消息 (B) 所示:

当你点击详情面板 (A) 中的信息按钮时,会出现一个文本框 (B) 解释为什么安装了这个版本而不是你请求的版本

依赖图 (Dependency Graph)

Package Manager 每次只能安装一个包版本,因此它必须构建一个依赖图(dependency graph),这是一份项目中每个直接和间接依赖项的列表。依赖图决定了每个包的安装版本。

锁定文件 (Lock File)

当 Package Manager 成功解决所有版本冲突时,它会将解析结果保存到一个锁定文件(lock file )中,以确保确定性(即每次都能可靠地安装相同的包),并减少再次计算依赖图所需的时间和资源。

全局缓存 (Global Cache)

当 Unity Package Manager 获取 UPM 包时,它会将包内容和元数据存储在全局缓存中。这使得重用和共享包更加高效,并且即使在离线时也能安装和更新已存储的包。

注意:将包存储在全局缓存中适用于从注册表获取的 UPM 包。从 Asset Store 获取的 UPM 格式的包也会存储在全局缓存中。然而,从 Asset Store 获取的 .unitypackage 格式的资产包不会存储在全局缓存中。Package Manager 将资产包存储在一个单独的缓存中。有关更多信息,请参阅Asset Store 包

位置 (Location)

默认情况下,Unity 将全局缓存存储在一个取决于操作系统(以及 Windows 上的用户帐户类型)的根目录中:

操作系统 (Operating System)默认根目录 (Default Root Directory)
Windows(用户帐户)%LOCALAPPDATA%\Unity\cache
Windows(系统用户帐户)%ALLUSERSPROFILE%\Unity\cache
macOS$HOME/Library/Unity/cache
Linux$HOME/.config/unity3d/cache
提示:你可以覆盖此根目录的位置。有关更多信息,请参阅自定义全局缓存位置

结构 (Structure)

Package Manager 全局缓存使用两种不同的辅助缓存(subsidiary caches),每种缓存服务于不同的目的。Package Manager 将这些辅助缓存存储在全局缓存文件夹下的子目录中:

子文件夹 (Subfolder)描述 (Description)
npm存储使用 npm 协议从注册表获取的数据。这包括包元数据和包 tarballs。
packages此缓存包含从注册表获取的包 tarballs 的解压内容。
git-lfs如果启用了 Git LFS,则此缓存包含下载的 Git 大文件存储 (LFS) 文件。
在这些子文件夹中的每个子文件夹内,每个注册表都有自己的路径,以确保托管在不同注册表上的包不会混淆。

提示:你可以覆盖这些文件夹的位置。有关更多信息,请参阅自定义全局缓存位置

要求 (Requirements)

运行 Unity 编辑器进程的用户帐户必须对根目录及其内容具有完全写入权限。没有这些权限,Package Manager 无法下载和保存包的元数据和内容到缓存中。

配置

配置文件

Package Manager 支持两个配置文件:全局配置文件和用户配置文件。这两个文件都使用 TOML 格式,并出现在不同的位置:

  • 全局配置文件(Global configuration files):适用于机器上的所有用户。例如,当为整台机器设置代理服务器时,可以定义额外的 SSL 证书颁发机构。
  • 用户配置文件(User configuration files):适用于单个用户。例如,可以设置认证令牌,以便访问带有范围注册表的自定义包注册表服务器。这些令牌会认证特定的用户账户。

全局配置文件位置

Package Manager 使用名为 upmconfig.toml 的全局配置文件。安装 Unity Hub 或编辑器时不会创建此文件,但如果需要自定义配置,可以在以下位置创建它:

  • Windows%ALLUSERSPROFILE%\Unity\config\upmconfig.toml(例如,C:\ProgramData\Unity\config\upmconfig.toml
  • macOS 和 Linux/etc/upmconfig.toml

您可以定义一个自定义位置来覆盖配置文件的默认位置。为此,请创建一个名为 UPM_GLOBAL_CONFIG_FILE 的环境变量,并将其值设置为配置文件的绝对路径(包括文件名)。

用户配置文件位置

Package Manager 使用名为 .upmconfig.toml 的用户配置文件。安装 Unity Hub 或编辑器时不会创建此文件,但如果需要自定义配置,可以在以下位置创建它:

  • Windows(用户账户)%USERPROFILE%\.upmconfig.toml(例如,C:\Users\myusername\.upmconfig.toml
  • Windows(系统用户账户)%ALLUSERSPROFILE%\Unity\config\ServiceAccounts\.upmconfig.toml(例如,C:\Users\Public\Unity\config\ServiceAccounts\.upmconfig.toml
  • macOS 和 Linux~/.upmconfig.toml(例如,/Users/myusername/.upmconfig.toml

您可以定义一个自定义位置来覆盖配置文件的默认位置。为此,请创建一个名为 UPM_USER_CONFIG_FILE 的环境变量,并将其值设置为配置文件的绝对路径(包括文件名)。

Scoped registry authentication

一些组织在需要认证才能访问的私有包注册表上托管他们的包。如果您是这些组织的员工或客户,则必须使用 npm 认证配置范围注册表。要设置此配置,请获取 npm 认证令牌,然后将该令牌添加到您的用户配置文件中。

获取 npm 认证令牌

不同注册表提供商的创建和访问 npm 认证令牌的过程各不相同。例如,JFrog 的 Artifactory 仓库管理器使用与 npm 不同的程序来生成认证令牌。以下是一个典型过程,但您需要遵循特定包注册表提供商为您的范围注册表推荐的过程。

从 npm 获取认证令牌:

  1. 在您的计算机上本地安装 npm
  2. 在终端中输入以下命令登录到注册表:
$ npm login --registry <registry URL>
  1. 找到并打开生成的 .npmrc 文件。
  2. 找到 _authToken_auth 条目并复制其值(参见下例)。
  3. 根据注册表的不同,令牌字符串可以是全球唯一标识符 (GUID)、令牌或专有格式的字符串(proprietary-formatted string)。
.npmrc 文件示例

包含 _authToken 属性的 .npmrc 文件示例:

registry=https://example.com:1234/mylocation/
//example.com:1234/mylocation/:_authToken=<AUTH TOKEN>

包含 _auth 属性的 .npmrc 文件示例:

registry=https://example.com:1234/mylocation
_auth=<AUTH TOKEN>
email=<EMAIL>
always-auth=true

配置认证信息(Configure authentication information)

将每个需要认证的范围注册表的令牌信息存储在 [.upmconfig.toml](https://docs.unity3d.com/2022.3/Documentation/Manual/upm-config.html#upmconfigUser) user configuration file 中,使用 npmAuth 配置模式。一旦将这些信息保存到配置文件中,Package Manager 将在每次请求时提供认证信息。

按照以下步骤将认证信息添加到用户配置文件中:

  1. 找到 .upmconfig.toml 用户配置文件。如果文件不存在,请创建一个空文本文件。
  2. 根据您使用的是 Bearer (基于 token) 还是 Basic (Base64-encrypted) 认证机制,使用模式格式化您的认证信息。
[npmAuth."<REGISTRY URL>"]
<TOKEN-PROPERTY> = "<TOKEN-VALUE>"
email = "<EMAIL>"
alwaysAuth = <BOOLEAN>

以下表格解释了如何指定配置文件值:

条目描述
[npmAuth."<REGISTRY-URL>"]必需。注册表的 URL。例如,[npmAuth."https://example.com:8081/mylocation"]
<TOKEN-PROPERTY> = "<TOKEN-VALUE>"必需。从 npm 注册表生成的认证令牌。可以是 GUID、令牌或专有格式的字符串。例如,可以是 token = "<AUTH TOKEN>"(Bearer)或 _auth = "<BASE64 TOKEN>"(Basic)。
email可选。与注册表中的用户电子邮件匹配的用户的电子邮件地址。
alwaysAuth可选。如果包元数据和 tarballs 不在同一服务器上,请设置为 true。通常,您可以从生成的 .npmrc 文件中复制此值。
使用 Bearer 认证的示例
[npmAuth."http://localhost:8081/myrepository/mylocation"]
token = "NpmToken.2348c7ea-6f86-3dbe-86b6-f257e86569a8"
alwaysAuth = true

[npmAuth."http://localhost:4873"]
token = "eaJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZWFsX2dyb3VwcyI6WyJwYXNjYWxsIl0sIm5hbWUiOiJwYXNjYWxsIiwiZ3JvdXBzIjpbIn"

[npmAuth."https://api.bintray.example/npm/mycompany/myregistry"]
token = "aGFzY2FsbDo4ZWIwNTM5NzBjNTI3OTIwYjQ4MDVkYzY2YWEzNmQxOTkyNDYzZjky"
email = "username@example.com"
alwaysAuth = true

配置 Basic 认证信息

以下步骤使用 Azure DevOps 作为示例,但对任何使用个人访问令牌(PAT)的平台过程类似。

  1. 安装 Node.js(如果尚未安装)。
  2. 获取您的 Azure DevOps 个人访问令牌(PAT),并在后续步骤中使用。如果需要重新生成 PAT,请登录 Azure DevOps(https://dev.azure.com),并转到用户设置 > 个人访问令牌。有关使用 PAT 的信息,请参阅 Microsoft 文章使用个人访问令牌
  3. 从命令行运行以下命令:
node -e "require('readline').createInterface({input:process.stdin,output:process.stdout,historySize:0}).question('Enter PAT> ',p => {b64=Buffer.from(p.trim()).toString('base64');console.log(b64);process.exit();})"
 在 `Enter PAT` 提示下输入 `email:PAT`,替换:
* `email` 为与 Azure DevOps 账户相关联的电子邮件地址,以及 `.upmconfig.toml` 文件中指定的电子邮件。
* `PAT` 为您之前步骤中的 PAT。
  1. 该命令返回一个 Base64 加密的字符串。复制该字符串并将其分配为 .upmconfig.toml 文件中 _auth 键的值。
使用 Basic 认证的示例
[npmAuth."http://localhost:8081/myrepository/mylocation"]
_auth = "c19kaW5pcm9AaG90bWFpbC4jb206d3FzdzVhemU9Q=="
email = "username@example.com"
alwaysAuth = true

Package Manager 窗口 (Package Manager Window)

使用 Package Manager 窗口,你可以:

  • 查看哪些包和功能集可供安装或已在项目中安装。
  • 检查哪些包版本可用。
  • 安装、更新或移除 UPM 包或功能集。
  • 下载并导入、更新或移除资产包 (asset packages)。
  • 禁用内置包 (built-in packages)。

Package Manager 窗口

Package Manager 窗口显示:

(A) 实验包指示器,用于警告你的项目包含实验包。

(B) 添加按钮,可以点击通过输入 Git URL、本地路径或包名直接将包安装到项目中。

© 包菜单,用于更改列表中显示的内容(上下文)。

(D) 排序菜单,用于按名称或日期排序包和功能集列表。

(E) 过滤器菜单和清除过滤器按钮,显示在所有列表中,除了内置列表。过滤器可以让你缩小列表中显示的包。

(F) 高级菜单,可以访问 Package Manager 的项目设置等。详细信息请参阅高级设置(Advanced settings)。

(G) 搜索框,可用于按名称搜索包和功能集。

(H) 列表视图,显示符合你指定的过滤器和搜索参数的包。所有选项卡列出所有符合你过滤器和搜索标准的包,而服务选项卡则进一步过滤列表以显示服务。

(I) 详细视图,显示列表中选定的功能集或包的具体信息。

(J) 包详情标签,显示所选功能集或包的详细信息。这些标签是动态的,基于所选项目。有关这些标签的更多信息,请参阅详细视图。

(K) 按钮可以在项目级别执行以下操作:

  • 安装或移除功能集
  • 安装、更新或移除 UPM 包
  • 下载并导入或更新资产包
  • 禁用或启用内置包

(L) 状态栏,当 Package Manager 加载包和功能集时显示信息。此信息包括错误和警告消息、可用的 Asset Store 包数量以及加载更多包的链接。

(M) 刷新列表按钮,让你刷新显示的包列表。在“我的资产”上下文中,刷新列表是一个菜单,包含“检查更新”选项,以便你检查计算机上所有包的更新;不仅仅是“我的资产”上下文中可见的那些包。

高级设置 (Advanced Settings)

高级设置菜单允许你执行以下操作:

菜单项 (Menu Item)操作结果 (Action Results)
项目设置 (Project Settings)选择此项以打开 Package Manager 项目设置,可以:添加、编辑和删除项目中的 scoped registries。浏览 Unity 注册表时列出预发布包。
手动解析 (Manual Resolve)选择此项以强制 Package Manager 解析项目的包。如果需要,它会重新安装更改或丢失的包,并移除多余的包。
首选项 (Preferences)选择此项以查看和设置 Unity 编辑器及相关窗口和工具的首选项。
将包重置为默认值 (Reset Packages to defaults)选择此项以恢复 Package Manager 默认设置。警告:这会移除项目清单文件中的所有自定义内容。仅当无法确定项目清单文件问题时,将此操作作为最后的手段。

包列表上下文 (Packages List Context)

要更改列表中显示的包,请从 Package Manager 窗口的 Packages 下拉菜单中选择你想要的上下文。

设置要在列表中显示的包的上下文

你可以从以下选项中进行选择:

上下文 (Context)描述 (Description)
Unity Registry显示 Unity 包注册表中的所有功能集和包,无论它们是否已安装到你的项目中。这不包括从其他位置或任何 scoped 注册表安装的包。这是默认的列表上下文。
My Registries显示此项目中从任何 scoped 注册表中可用的包。注意:如果你添加了 scoped 注册表但在 My Registries 上下文中看不到它,或者 My Registries 上下文根本不可用,可能是因为你添加的包注册服务器未实现 /-/v1/search/-/all 端点(endpoints),这意味着它不兼容 Unity 的 Package Manager。
In Project显示当前项目中已安装的所有功能集和包,包括本地、Git 和嵌入式包,以及从任何注册表安装的包。
My Assets显示你使用当前登录的 Unity ID 购买的所有 Asset Store 包 (.unitypackage)。
Built-in仅显示内置的 Unity 包,这些包代表一些核心的 Unity 功能。你可以使用这些包来打开和关闭 Unity 模块。提示:你可以在 Unity Scripting API 中找到有关每个内置包(模块)实现的更多信息。每个模块程序集页面列出内置包实现的 API。

Scoped Registries

Scoped registries 允许 Unity 与任何自定义包注册服务器的位置进行通信,以便用户可以同时访问多个包集合。以下是一些重要概念,帮助你理解此功能:

概念 (Concept)描述 (Description)
包注册服务器 (package registry server)一种跟踪包并提供存储包位置的应用程序。在 Unity 的 Package Manager 窗口中,当你选择 Unity Registry 上下文时,所有在 Unity 注册表中注册的包都会出现在列表视图中。
包管理器 (package manager)一种告诉用户有哪些包可用,并下载和安装用户请求的包的应用程序。Unity 实现了自己版本的包管理器,但在其他组织中也有类似的应用程序。
范围 (scope)定义包名或命名空间(反向域格式, reverse domain format),如 com.example.mycompany.animationcom.example。当用户请求一个包时,Package Manager 会从最符合范围的注册表中获取该包。有关更多信息,请参阅下文中的“管理项目的 scoped registries”。
与 scoped registries 的交互方式取决于你的角色:
  • 包提供者 (Package Providers) 设置自定义注册服务器以托管和分发自定义包,除了 Unity 注册表。
  • 包消费者 (Package Consumers) 为每个项目设置 scoped registries,以访问自定义包提供者的注册服务器。

scoped registries 的完整性和安全性

作为包提供者,请确保你设置的任何包注册服务器都符合 Unity 的服务条款和 Unity 的包指导原则和指南。Unity 提供 Package Manager 以促进知识和创作的共享,但不是用于第三方产品的市场。

作为包消费者,当你安装 scoped registry 时,请像安装任何其他第三方软件一样谨慎:

  • 仅从可信来源安装 scoped registries,因为这些注册表中的包可能包含可执行代码。
  • 注意可能有害的第三方注册表或未经适当控制而捕获数据的注册表。也要警惕那些冒充 Unity 或被 Unity 批准或支持的第三方。

scoped registries 的好处

scoped registries 可以帮助:

  • 提供新功能:通过分发工具、库和其他资源。
    • 作为提供者,你可以创建自己的注册表来分发工具和脚本(或其他类型的资源),并使用版本号指示包的成熟度。版本号还表明更新是引入了破坏性 API 更改还是小修复,基于语义版本控制 (Semantic Versioning)。你的代码可以依赖于其他包中的代码,因为 Package Manager 支持包依赖。
    • 作为消费者,你在 Package Manager 中浏览和安装第三方自定义包的体验与浏览 Unity 的包相同。
  • 扩展现有 Unity 包功能:作为消费者,你可以拥有无缝体验,自定义包覆盖 Unity 包,而无需手动切换注册表或显式安装不同的包版本。这是因为你可以将包映射到特定的注册表,以便 Package Manager 从 Unity 注册表或自定义包注册服务器中获取包。
  • 访问封闭网络环境中的包:一些组织在封闭网络内工作,这使得访问 Unity 自身的包注册表变得困难。在这些情况下,组织可以在封闭网络内的服务器上设置自己的包注册表。网络管理员可以定期与 Unity 的包注册表同步,以确保 scoped registry 拥有最新的可用包集合。

如果你是包消费者,请参阅管理项目的 scoped registries 以获取有关在 Unity 项目中连接到现有自定义包注册服务器的信息。如果你是包生产者,请参阅共享你的包以获取有关支持的包注册服务器的信息,并获取有关如何设置它们以与 scoped registries 一起使用的链接。

注意:如果你正在设置一个指向具有受限访问权限的包注册服务器的 scoped registry,可以配置 Package Manager 将你的 npm 认证令牌传递给服务器。有关更多信息,请参阅scoped registry 认证

导入 scoped registries

如果你在一个共享项目中工作,并且另一个用户向项目添加了一个 scoped registry,Unity 会警告你有用户添加了一个新的 scoped registry。

Unity 会警告你如果项目的 scoped registries 列表发生了变化

当你点击关闭按钮时,会出现 Package Manager 项目设置窗口,让你可以为项目添加、修改或删除 scoped registries。

如果你点击“阅读更多”按钮,Unity 会在默认网络浏览器中打开你当前阅读的页面。

提示:要随时访问 Package Manager 项目设置窗口,请使用 Unity 主菜单 (Edit > Project Settings,然后选择 Package Manager 类别) 或从 Package Manager 窗口的高级项目设置菜单中选择 Advanced Project Settings。

管理项目的 scoped registries

要管理项目中的 scoped package registries,你可以直接编辑项目清单(project manifest)文件,或者使用 Package Manager 项目设置窗口让 Unity 为你修改清单。

项目清单使用 scopedRegistries 属性,它包含一个 scoped registry 配置对象数组。每个对象包含以下属性:

属性 (Property)JSON 类型 (JSON Type)描述 (Description)
名称 (name)String在用户界面中显示的范围名称。Package Manager 窗口在包详情视图中显示此名称。例如,"name": "Tools"
URLStringnpm 兼容的注册服务器的 URL。例如,"url": "https://mycompany.example.com/tools-registry"注意:并非所有注册表提供者都兼容 Unity 的 Package Manager。确保你尝试添加的包注册服务器实现了 /-/v1/search 或 /-/all 端点。
范围 (scopes)Array of Strings可以映射到包名的范围数组,可以是包名的精确匹配,也可以是命名空间。通配符和其他 glob 模式不受支持。例如,"scopes": ["com.example", "com.example.tools.physics"]注意:这种配置类型假定包遵循反向域名表示法。这确保了 com.unity 等同于任何与 com.unity 命名空间匹配的包名,例如 com.unity.timeline 或 com.unity.2d.animation。警告:Unity 不支持 npm 的范围表示法。
当 Package Manager 决定从哪个注册表获取包时,它会将包名与 scopes 值进行比较,并找到范围值最接近的注册表。

例如,在下面的项目清单中,有两个 scoped registries,“General”和“Tools”:

{
    "scopedRegistries": [
        {
            "name": "General",
            "url": "https://example.com/registry",
            "scopes": [
                "com.example", "com.example.tools.physics"
            ]
        },
        {
            "name": "Tools",
            "url": "https://mycompany.example.com/tools-registry",
            "scopes": [
                "com.example.mycompany.tools"
            ]
        }
    ],
    "dependencies": {
        "com.unity.animation": "1.0.0",
        "com.example.mycompany.tools.animation": "1.0.0",
        "com.example.tools.physics": "1.0.0",
        "com.example.animation": "1.0.0"
    }
}

当 Package Manager 查找 com.example.animation 包时,发现 com.example 命名空间与其名称最接近,并从“General”注册表获取该包。

当 Package Manager 查找 com.example.tools.physics 包时,“General”注册表具有完全匹配包名的范围。

当 Package Manager 查找 com.example.mycompany.tools.animation 包时,Package Manager 发现 com.example.mycompany.tools 命名空间与其名称最接近,并从“Tools”注册表获取该包。尽管它也匹配“General”范围,但 com.example 命名空间并没有那么接近。

当 Package Manager 查找 com.unity.animation 包时,Package Manager 在任何 scoped registries 中都找不到匹配项,因此从默认注册表中获取该包。

解析与冲突 (Resolution and Conflict)

当你将一个包添加到项目清单 (project manifest) 中时,Unity 会将该包视为项目的依赖项(直接依赖项)。然而,一个包也可以依赖于其他包,这在任何需要该包的项目中会产生间接依赖项 (indirect dependencies)。

由于大多数项目在开发游戏和应用时需要多个包,Package Manager 必须评估所有请求的包版本(无论是直接的还是间接的),并决定安装哪些包版本。为此,它计算满足项目中所有直接和间接依赖项的包集,从项目依赖项开始,递归地探索每个间接依赖项,收集所有依赖信息,然后选择一组没有冲突的包来满足依赖要求。例如,下面的依赖图表示一个项目的四个直接依赖项及其所有间接依赖项:

项目的直接和间接包依赖图

在这个例子中:

  • 浅蓝色节点表示项目的直接依赖项。
  • 深蓝色节点表示在此项目中作为间接依赖项的相同包和版本。
  • 红色节点表示同一包的两个不同版本,这是一个冲突。

注意:只有使用版本声明的包依赖项需要解析。Package Manager 选择从其他来源安装的包,例如嵌入式包 (embedded packages) 和使用本地路径、Git URL 以及内置包声明的依赖项,而不是基于版本的依赖项。

选择最佳解决方案 (Choosing the Best Solution)

根据项目清单中定义的一组包,评估所有可能的包组合可能需要很长时间:一个项目可能依赖于数百个包,每个包又依赖于数百个其他包,并且大多数需要不同的版本。

示例 (Example)

在这个例子中,请求了多个版本的以下包:

  • burst@1.2.2(两次)和 burst@1.3.0-preview.3
  • collections@0.5.1-preview.11collections@0.5.2-preview.8
  • jobs@0.2.4-preview.11(两次)和 jobs@0.2.5-preview.20

使用直接和间接依赖项集,Package Manager 选择满足 collections@0.5.2-preview.8 包依赖项的最高版本 burst 包(burst@1.3.0-preview.3):

在依赖图中,蓝色节点指示 Package Manager 选择的版本

锁定文件 (Lock Files)

锁定文件包含 Package Manager 对项目依赖解析的结果。包管理器使用锁定文件在解析包依赖图时提供确定性结果。当 Unity Package Manager 计算出成功的解析时,它会将该解析存储在项目的 Packages 文件夹中的一个名为 packages-lock.json 的 JSON 文件中。对项目清单 (project manifest) 或可变包(无论是嵌入式包还是从本地文件夹安装的包)清单的任何修改,都可能促使 Package Manager 重新计算解析的包版本。但只要锁定文件中的包版本满足依赖版本和解析策略所暗示的范围,该包就会保持锁定在该版本。

例如,以下是锁定文件中的一个典型条目:

"com.unity.textmeshpro": {
  "version": "2.0.1",
  "depth": 0,
  "source": "registry",
  "dependencies": {
    "com.unity.ugui": "1.0.0"
  },
  "url": "https://packages.unity.com"
},
    etc.

当 Package Manager 解析任何冲突的间接依赖时,它会尽可能多地重用锁定的包。这保证了后续的依赖解析对相同的依赖集产生相同的结果。它还最小化了耗时的操作,如下载、解压或复制包。

如果没有只包含锁定包的解决方案,则 Package Manager 选择风险最小的升级包集,优先考虑补丁升级而不是次要或主要升级,次要升级优于主要升级。实际上,你可以自定义升级的风险等级。有关更多信息,请参阅自定义解析策略

要强制刷新间接依赖版本,请删除锁定文件。

不要手动修改锁定文件:Package Manager 会创建并维护锁定文件,因此它会覆盖你对文件所做的任何更改。

将锁定文件置于版本控制下,以便你可以始终如一地再现相同的包集,确保你的项目随时间和在不同机器上保持一致。

禁用锁定文件 (Disabling the Lock File)

默认情况下,Package Manager 成功计算依赖图时会创建或更新锁定文件。如果你看到意外的结果,可以在项目清单中将 enableLockFile 属性设置为 false 以禁用锁定。然而,如果禁用锁定文件,Package Manager 会再次克隆 Git URL 包,这会导致性能下降和额外的网络使用。如果你在两次解析之间将新的提交推送到远程 Git 仓库,这也可能导致非确定性结果。

项目清单 (Project Manifest)

当 Unity 加载一个项目时,Unity Package Manager 会读取项目清单,以便计算需要检索和加载的包列表。当用户通过 Package Manager 窗口安装或卸载包时,Package Manager 会将这些更改存储在项目清单文件中。项目清单文件通过 dependencies 对象管理包列表。

此外,项目清单还充当 Package Manager 的配置文件,Package Manager 使用清单来自定义注册表 URL 并注册自定义注册表。

你可以在 Unity 项目根文件夹下的 Packages 文件夹中找到名为 manifest.json 的项目清单文件。与包清单文件类似,项目清单文件使用 JSON(JavaScript 对象表示法)语法。

属性 (Properties)

所有属性都是可选的。然而,如果你的项目清单文件不包含任何值,Package Manager 窗口将无法加载,并且 Package Manager 不会加载任何包。

提示:你可以随时通过选择 Unity 帮助菜单中的“重置包为默认值”来解决你的注册表问题。然而,请注意,这个操作会重置你对项目依赖项所做的所有更改,所以最好在最后手段时才使用此操作。

键 (Key)JSON 类型 (JSON Type)描述 (Description)
dependenciesObject项目所需的包集合。这仅包括直接依赖项(间接依赖项列在包清单中)。每个条目将包名映射到项目所需的最低版本:{``"dependencies": {``"com.my-package": "2.3.1",``"com.my-other-package": "1.0.1-preview.1",``etc.``}``}指定版本号表示你希望 Package Manager 从包注册表中下载包(即包的来源是注册表)。除了使用版本号,你还可以指定本地文件夹或 tarball 文件的路径,或者 Git URL。
注意:你不需要在这里指定嵌入包,因为 Package Manager 会在你的项目的 Packages 文件夹中找到它们并自动加载。如果存在具有相同名称的嵌入包,Package Manager 会忽略任何条目。
enableLockFileBoolean启用锁定文件以确保依赖项以确定性方式解析。默认设置为 true。有关更多信息,请参阅 使用锁定文件
resolutionStrategyString根据语义版本控制规则升级间接依赖项。默认设置为 lowest。有关更多信息,请参阅下文中的设置解析策略。
scopedRegistriesArray of Objects除了默认注册表外,还指定自定义注册表。这允许你托管自己的包。有关更多详细信息,请参阅 Scoped Registries
testablesArray of Strings列出你希望在 Unity Test Framework 中加载其测试的包名。有关更多信息,请参阅 Adding tests to a package。注意:你不需要在这里指定嵌入包,因为 Unity Test Framework 默认认为它们是可测试的。

示例 (Example)

{
  "scopedRegistries": [{
    "name": "My internal registry",
    "url": "https://my.internal.registry.com",
    "scopes": [
      "com.company"
    ]
  }],
  "dependencies": {
    "com.unity.package-1": "1.0.0",
    "com.unity.package-2": "2.0.0",
    "com.company.my-package": "3.0.0",
    "com.unity.my-local-package": "file:<path>/my_package_folder",
    "com.unity.my-local-tarball": "file:<path>/my_package_tarball.tgz",
    "com.unity.my-git-package": "https://my.repository/my-package.git#v1.2.3"
  },
  "enableLockFile": true,
  "resolutionStrategy": "highestMinor",
  "testables": [ "com.unity.package-1", "com.unity.package-2" ]
}

设置解析策略 (Setting a Resolution Strategy)

虽然你可以通过将间接依赖项显式添加到项目清单中来强制 Unity 的包依赖解析使用更高版本,但这并不是一个好的策略,原因有二:

  1. 这会增加项目所有者维护依赖版本的责任。
  2. 随着时间推移,你可能会有一些项目不需要的依赖项。

更好的方法是根据语义版本控制规则自定义 Package Manager 如何选择间接依赖项,方法是设置 resolutionStrategy 属性:

值 (Value)描述 (Description)
lowest不升级间接依赖项。使用确切请求的版本。这是默认模式。
highestPatch升级到具有相同 Major 和 Minor 组件的最高版本。例如,使用请求版本 1.2.3,此策略选择范围 [1.2.3, 1.3.0) 内的最高版本(即 >= 1.2.3< 1.3.0)。
highestMinor升级到具有相同 Major 组件的最高版本。例如,使用请求版本 1.2.3,此策略选择范围 [1.2.3, 2.0.0) 内的最高版本(即 >= 1.2.3< 2.0.0)。
注意:版本 1.0.0 标志着第一个稳定、适用于生产的版本。低于该版本的 0.X.Y 版本表示其 API 尚不稳定,后续的小版本可能引入破坏性更改。语义版本控制规范的这一部分允许在不影响快速开发的情况下发布包的早期版本。因此,当目标版本为 0.X.Y 时,highestMinor 行为类似于 highestPatch,以确保选择向后兼容的版本。例如,使用请求版本 0.1.3,此策略选择范围 [0.1.3, 0.2.0) 内的最高版本。

嵌入依赖项 (Embedded Dependencies)

任何出现在项目 Packages 文件夹下的包都嵌入在该项目中。你可以通过几种方式创建嵌入包:

  1. 直接在项目的 Packages 文件夹中创建一个新包。
  2. 手动将 Unity 包从项目的包缓存复制到项目的 Packages 文件夹中。
  3. 使用 C# 脚本嵌入已经安装的包的版本。

嵌入包不需要作为依赖项出现在项目清单 (project manifest) 中。然而,如果你嵌入了一个已安装包的版本,项目清单仍会列出对原始已安装版本的依赖。在这种情况下,磁盘上的包优先于列为依赖项的包版本,因此不需要将其从项目清单中删除。例如,如果项目清单指定了对 com.unity.example 包版本 1.3.1 的依赖,但项目中也有一个具有相同名称的嵌入包,Package Manager 将使用嵌入包,而不论其表面版本如何,而不是从注册表下载 1.3.1 版本。

确保你跟踪嵌入包的内容及其所做的任何更改。如果你的 Unity 项目在版本控制下,请将嵌入在该项目中的任何包添加到相同的版本控制中。

创建一个新的自定义包 (Creating a New Custom Package)

要嵌入一个新包,在 Packages 文件夹下的一个文件夹内创建你的新包内容。有关更多信息,请按照创建你自己的自定义包的说明进行操作。

通常,新包会嵌入在你的项目中,直到你准备与其他用户分享并在其他项目中测试它为止。然后,你可以将其发布到一个 scoped 包注册表。

从缓存中复制 Unity 包 (Copying a Unity Package from the Cache)

从注册表安装的包是不可变的 (immutable),这意味着你不能编辑它。如果你想编辑包,可以通过将其复制到项目文件夹中使其变为可变的 (mutable)。这种包类型称为嵌入包,它会覆盖包缓存中的内容。之后,你可以从项目文件夹中删除该嵌入包的文件夹,Package Manager 会自动切换回不可变的缓存包。

找到包在缓存中的文件夹的最可靠方法是直接在 Unity 编辑器中找到已安装的版本:

  1. 打开 Project 窗口,方法是打开 Window 菜单并选择 General > Project
  2. Project 窗口中,找到你想要嵌入的已安装包。
  3. 右键点击所选包的文件夹,选择 Show in Explorer(Windows)或 Reveal in Finder(macOS)。该包的文件夹会直接在文件浏览器中打开,并使用 <package-name>@<package-version> 命名约定。

注意:如果你想嵌入的包不在项目中,可以使用文件浏览器或命令行直接从项目的包缓存 (<project>/Library/PackageCache) 获取它,并导航到正确的文件夹。然而,让编辑器为你找到它更可靠,因为除了定位项目缓存中的包,它还可以定位从本地文件夹或 tarball 安装的包,以及已嵌入的包。

文件浏览器打开项目包缓存下的包文件夹

复制包文件夹并直接粘贴到项目的 Packages 文件夹中。不要将其放在**Assets**文件夹内,因为 Package Manager 不会扫描该文件夹中的包。

移除文件夹名称中的 @<package-version> 部分。

如果你的项目已经在版本控制下,请将新嵌入的包添加到版本控制中。

注意:你也可以在全局缓存下找到包文件夹,但全局缓存包含你系统上曾安装的所有版本的 Unity 编辑器的包,因此请注意选择与你项目的编辑器版本兼容的版本。

如果你想删除嵌入包,请使用文件浏览器或命令行在 Packages 文件夹中找到该包。考虑备份嵌入包的文件夹,否则你会丢失对包所做的任何更改。然后,从 Packages 文件夹中删除该包的文件夹。Package Manager 会自动还原到不可变的缓存包。

创建自定义包 (Creating Custom Packages)

Unity Package Manager 是 Unity 的官方包管理系统。它具有以下功能:

  • 允许 Unity 快速、轻松地分发新功能和更新现有功能。
  • 提供一个平台供用户发现和共享可重用的组件。
  • 促进 Unity 作为一个可扩展和开放平台的发展。

你可以使用 Package Manager 定义项目依赖项、解决包依赖项、下载包、添加包以及将内容集成到项目中。

有关包的定义以及 Unity Package Manager 如何工作的一般信息,请参阅包文档。

概述 (Overview)

包可以包含以下内容:

  • C# 脚本
  • 程序集
  • 原生插件(native plug-ins)
  • 模型、纹理、动画和音频剪辑等资产

注意:Package Manager 不支持包中的流媒体资产。请使用 Addressables 包代替。

每个包还包含一个包清单文件 (Package Manifest),其中包括包名、版本、依赖项列表及其存储库 URL 等信息。

步骤 (Procedure)

要创建一个新包:

  1. 使用以下方法之一创建包的空外壳:
    • 设置嵌入包 (embedded package)。
    • 设置本地包 (local package)。
  2. 确保文件夹结构的布局遵循 Unity 包的布局约定。例如,如果你有 Editor 和 Runtime 库,请确保将它们存储在 Editor 和 Runtime 文件夹中。
  3. 如果你的包包含代码,请确保创建的包布局中具有必要的程序集定义文件。有关创建和定义程序集定义文件的信息,请参阅程序集定义和包。有关更多信息,请参阅程序集定义。

注意:如果在添加程序集定义文件后控制台窗口报告警告,请保存项目,关闭它,然后重新打开。

  1. 添加包所需的工具、库和任何资产。
  2. 向包中添加测试。测试对于确保包在不同场景中按预期工作至关重要:
    • 将所有编辑器测试编写在 Tests/Editor 文件夹中。
    • 将所有播放模式测试编写在 Tests/Runtime 文件夹中。
  3. 如果你有包的样本,请将它们添加到适当的 samples 子文件夹中。

注意:包可以仅包含样本,但你也可以使用相同的布局和 JSON 结构将样本作为工具或模板包的一部分包含在内。

  1. 每次发布新版本时,更新 CHANGELOG.md 文件。每个新功能或错误修复都应该在此文件中有所记录。有关所选更改日志格式的详细信息,请参阅保持更改日志文档。

对于不共享的包,此步骤是可选的,但对于共享包强烈建议执行此步骤,以便用户知道哪个版本最适合他们的需求。

提示:你可以通过在包的 package.json 清单文件中设置 changelogUrl 属性来提供一个链接到托管此包的更改日志的外部网页。

  1. 你可以在 LICENSE.mdTHIRD PARTY NOTICES.md 文件中包含许可和第三方通知。

对于不共享的包,此步骤是可选的,但对于共享包强烈建议执行此步骤,以便用户不会滥用你的包或违反任何第三方许可证。

提示:你可以通过在包的 package.json 清单文件中设置 licensesUrl 属性来提供一个链接到托管此包的许可和第三方通知的外部网页。

  1. 编写包的文档。

提示:你可以通过在包的 package.json 清单文件中设置 documentationUrl 属性来提供一个链接到托管此包的文档的外部网页。

  1. 共享你的包。

创建一个新的嵌入包 (Creating a New Embedded Package)

如果你想在项目文件夹中创建自定义包,请按照以下说明进行操作。

注意:这些说明是创建自定义包的更大步骤的一部分。

  1. 打开 Unity Hub,并在你的计算机上创建一个空项目。

你也可以使用计算机上的现有项目,并将包嵌入到项目中或从本地文件夹安装包。然而,从一个新项目开始可以使包内容更不容易出错。

  1. 使用计算机的文件管理器(例如 Windows 文件资源管理器或 macOS Finder),导航到项目文件夹并找到 Packages 子目录。
  2. 使用与你的包名匹配并遵循命名约定的名称,在 Packages 文件夹内创建一个新的子目录。例如,如果你的包名是 com.example.mypackage,请创建一个名为 com.example.mypackage 的子目录。

注意:如果你的包包含资产,这一点尤其重要,因为 AssetDatabase 查找与 Packages/<your-package-name>/Assets 匹配的资产路径,而不管实际的文件夹名称如何。

  1. 打开你喜欢的文本编辑器,在包文件夹的根目录中创建一个名为 package.json 的 JSON 文件。
  2. 填写 package.json 文件中的所有必填和推荐字段。你可以使用包清单示例作为参考。

当你重新打开 Unity 时,新包会出现在 Package Manager 窗口和 Project 窗口中,在那里你可以查看和修改包内容。如果你在 Project 窗口中选择 package.json 文件,还可以在 Inspector 窗口中直接修改其 JSON 值。

返回主步骤以完成包的创建。

创建一个新的本地包 (Creating a New Local Package)

如果你想在项目文件夹之外创建自定义包,请按照以下说明进行操作。

注意:这些说明是创建自定义包的更大步骤的一部分。

  1. 使用计算机的文件管理器(例如 Windows 文件资源管理器或 macOS Finder),为你的包创建一个文件夹。
    你也可以使用已创建一些包内容的现有位置。
  2. 打开你喜欢的文本编辑器,在包文件夹的根目录中创建一个名为 package.json 的 JSON 文件。
  3. 填写 package.json 文件中的所有必填和推荐字段,确保 name 属性遵循命名约定。你可以使用包清单示例作为参考。
  4. 在 Unity 中,创建一个新项目或打开一个现有项目。
  5. 打开 Package Manager 窗口,并按照安装本地包的说明(installing a local package),使用你刚刚创建的 package.json 文件。此步骤对于确保创建所需的 .meta 文件至关重要。

新包会出现在 Package Manager 窗口和 Project 窗口中,在那里你可以查看和修改包内容。如果你在 Project 窗口中选择 package.json 文件,还可以在 Inspector 窗口中直接修改其 JSON 值。

返回主步骤以完成包的创建。

包布局 (Package Layout)

以下是自定义包的推荐包布局:

<package-root>
  ├── package.json
  ├── README.md
  ├── CHANGELOG.md
  ├── LICENSE.md
  ├── Third Party Notices.md
  ├── Editor
  │   ├── <company-name>.<package-name>.Editor.asmdef
  │   └── EditorExample.cs
  ├── Runtime
  │   ├── <company-name>.<package-name>.asmdef
  │   └── RuntimeExample.cs
  ├── Tests
  │   ├── Editor
  │   │   ├── <company-name>.<package-name>.Editor.Tests.asmdef
  │   │   └── EditorExampleTest.cs
  │   └── Runtime
  │        ├── <company-name>.<package-name>.Tests.asmdef
  │        └── RuntimeExampleTest.cs
  ├── Samples~
  │        ├── SampleFolder1
  │        ├── SampleFolder2
  │        └── ...
  └── Documentation~
       └── <package-name>.md

许多官方的 Unity 包也实现了这种结构。

位置和描述 (Location and Description)

位置 (Location)描述 (Description)
package.json包清单 (package manifest),定义了包依赖项和其他元数据。
README.md开发者包文档。通常是帮助希望更改包或在包的主分支上推送新更改的开发者的文档。
CHANGELOG.md以逆序排列的包更改描述。最好使用标准格式,如保持更改日志
LICENSE.md包含包的许可证文本。通常 Package Manager 会从所选的 SPDX 列表网站复制文本。
Third Party Notices.md包含满足法律要求所需的信息。
Editor/特定于 Editor 平台的资产文件夹。与 Assets 下的 Editor 文件夹不同,这仅仅是一个约定,不会影响资产导入管道。请参阅程序集定义和包以正确配置此文件夹中的特定于 Editor 的程序集。
Runtime/特定于 Runtime 平台的资产文件夹。这仅仅是一个约定,不会影响资产导入管道。请参阅程序集定义和包以正确配置此文件夹中的 Runtime 程序集。
Tests/用于存储包中包含的任何测试的文件夹。
Tests/Editor/特定于 Editor 平台的测试文件夹。请参阅程序集定义和包以正确配置此文件夹中的特定于 Editor 的测试程序集。
Tests/Runtime/特定于 Runtime 平台的测试文件夹。请参阅程序集定义和包以正确配置此文件夹中的 Runtime 测试程序集。
Samples~/用于存储包中包含的任何样本的文件夹。
Documentation~用于存储包中包含的任何文档的文件夹。

Unity 会忽略任何名称以 ~ 字符结尾的文件夹内容,并且不会使用 .meta 文件进行跟踪。然而,你需要为 EditorRuntimeTests 文件夹及其内容包含 .meta 文件,以确保它们正常工作。有关 .meta 文件及其在 Unity 中的使用信息,请参阅资产工作流

程序集定义和包 (Assembly Definition and Packages)

在包中,必须将脚本 (scripts) 关联到程序集定义文件 (.asmdef)。程序集定义文件是 Unity 中相当于 .NET 生态系统中的 C# 项目。你必须在程序集定义文件中显式引用其他程序集(无论是在同一个包中还是在外部包中)。有关详细信息,请参阅程序集定义

使用以下约定命名和存储你的程序集定义文件,以确保编译的程序集文件名遵循 .NET Framework Design Guidelines

  1. 将特定于 Editor 的代码存储在根 Editor 程序集定义文件下:
Editor/<company-name>.<package-name>.Editor.asmdef
  1. 将特定于 Runtime 的代码存储在根 Runtime 程序集定义文件下:
Runtime/<company-name>.<package-name>.asmdef
  1. 为你的 Editor 和 Runtime 脚本配置相关的测试程序集:
Tests/Editor/<company-name>.<package-name>.Editor.Tests.asmdef
Tests/Runtime/<company-name>.<package-name>.Tests.asmdef

要了解推荐的包文件夹布局的总体视图,请参阅包布局

示例文件 (Example File)

在此示例中,程序集定义文件引用了它自己的程序集以及作为包依赖项的一部分的程序集 (HDRP):

{
    "name": "MyCompany.MyPackageName",
    "references": [
        "MyCompany.MyPackageName.Tools",
        "MyCompany.MyPackageName.Planes",
        "Unity.RenderPipelines.HighDefinition.Runtime"
    ],
    "includePlatforms": [],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "overrideReferences": false,
    "precompiledReferences": [],
    "autoReferenced": true,
    "defineConstraints": [],
    "versionDefines": [
        {
            "name": "com.unity.render-pipelines.high-definition",
            "expression": "7.1.0",
            "define": "HDRP_7_1_0_OR_NEWER"
        },
        {
            "name": "com.unity.modules.particlesystem",
            "expression": "1.0.0",
            "define": "USING_PARTICLE_SYSTEM"
        }
    ],
    "noEngineReferences": false
}

有关程序集定义文件结构的详细信息,请参阅程序集定义文件格式

参考

  1. https://docs.unity3d.com/cn/current/Manual/Packages.html
  2. https://openupm.com/

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部