# CCD + Addressables 演练

> Follow this workflow to integrate the Addressable Asset system with Cloud Content Delivery for seamless content delivery.

本节演示如何为实际的 Unity 游戏项目设置 Cloud Content Delivery (CCD) 和 [Addressables](https://docs.unity3d.com/Packages/com.unity.addressables@latest/)，以便您可以轻松地将 Unity 编辑器的资源管线集成到 CCD 中。

> **Note:**
>
> 使用 CCD 不需要 Addressables 可寻址资源系统。

借助非常简单的移动端游戏《Loady Dungeons》，您将学习如何：

* [使用可寻址资源来配置和管理资源](#configuring-game-assets-as-addressable)
* [生成 AssetBundles](#generate-assetbundles)
* [在 Unity Dashboard（Unity 后台）中设置项目](#get-started-with-cloud-content-delivery)
* [设置命令行界面](#the-command-line-interface-optional)
* [在 CCD 后台中创建存储桶和标示](#buckets)
* [上传 AssetBundles](#uploading-the-content)

阅读本演练的内容后，您将了解如何有效地向用户提供内容，以及如何将 Unity 中的可寻址资源系统与 CCD 配合使用。

> **Note:**
>
> 本演练使用 Unity 2021.3.18f1。

## 下载项目##prerequisites

为了按照本演练进行操作，首先需要从 GitHub 下载最新版本的示例游戏[《Loady Dungeons》](https://github.com/UnityTechnologies/LoadyDungeons/releases/tag/t0.2.0)。

## 测试项目##configure-addressables-in-the-editor

1. 打开 Unity 编辑器。

2. 打开 Loady Dungeons 项目。

3. 打开 MainMenu 场景。

4. 单击 Game（游戏）选项卡。

5. 在 Aspect（宽高比）下拉选单中，单击 **+**。

   1. 创建 **Type（类型）** 为“Aspect Ratio（宽高比）”的新宽高比，并将其 **Width（宽度）** 和 **Height（高度）** 分别设置为 9 和 16。这样的设置会使得游戏预览看起来更像是在手机上运行。
   2. 单击 **OK（确定）**。
   3. 取消选择 **Low Resolution Aspect Ratios（低分辨率宽高比）**。

6. 按编辑器的 **Play（运行）** 按钮尝试运行游戏。

> **Note:**
>
> 在初始状态下运行游戏意味着您无法加载第一个关卡。在本演练的推进过程中，我们会关联 CCD 与 Addressables 结合使用时所需的资源来解决这一限制。

## 安装 Addressables 资源包##connect-your-project-to-ccd

为了将资源标记为可寻址 (addressable)，您需要直接在 Unity 编辑器中安装 Addressables 包。

> **Note:**
>
> 此项目已经预装了 Addressables 包，但如果您要使用自定义项目进行操作或想要升级到已验证的更高版本，请通过 [Package Manager（包管理器）](https://docs.unity3d.com/Manual/upm-ui.html)安装 Addressables 包。

1. 选择 **Window（窗口）**> **Package Manager（包管理器）**。
2. 搜索已针对您当前所使用的 Unity 编辑器版本进行了验证的最新版本的 Addressables 包。此示例使用版本 1.16.19。
3. 选择所需的版本，然后选择 **Install（安装）**。

## 将游戏资源配置为可寻址##configuring-game-assets-as-addressable

[可寻址资源](https://docs.unity3d.com/Packages/com.unity.addressables@latest/)支持按地址加载资源，提供了一种处理资源管理过载的简单方法。安装好 Addressables 包之后，接下来可以将游戏资源标记为可寻址。

1. 在 Project（项目）窗口中打开 Scenes 文件夹。

2. 选择以下资源：

   * Level\_00
   * Level\_01
   * Level\_02
   * Level\_03

3. 在 Inspector（检视面板）窗口中，为每个资源选择 **Addressable（可寻址）**。

4. 从 **Window（窗口）**> **Asset Management（资源管理）**> **Addressables** > **Groups（组）** 打开 Addressables Groups（Addressables 组）窗口。

5. 使用 **Create（创建）**> **Group（组）**> **Packed Assets（打包资源）** 创建以下新组：

   * Level 00
   * Level 01
   * Level 02
   * Level 03
   * Hats

6. 将 Scenes 资源从默认组拖动到其对应的组中。例如，将 Level\_01 场景从默认组拖动到您新创建的 Level 01 组中。

7. 将 Project（项目）窗口中的 Hats 文件夹（选择 **Prefabs（预制件）**> **Hats（帽子）**）中的全部内容（不是文件夹本身）拖到 Hats 组中。

8. 从 Addressables Groups（Addressables 组）窗口中选择每个资源，然后在 Inspector（检视面板）窗口中将该资源冗长的 Addressable（可寻址）字段重命名为更简洁的名称。您可以选择所有资源，然后**右键单击** > **Simplify Addressable Names（简化可寻址资源名称）** 来自动进行重命名。

   对于场景资源 Level\_00，可将其 Addressable（可寻址）字段从 Assets/Scenes/Level\_00.unity 重命名为 Level\_00。

   * 将场景资源 Level\_00 的 Addressable（可寻址）字段重命名为 Level\_00
   * 将场景资源 Level\_01 的 Addressable（可寻址）字段重命名为 Level\_01
   * 将场景资源 Level\_02 的 Addressable（可寻址）字段重命名为 Level\_02
   * 将场景资源 Level\_03 的 Addressable（可寻址）字段重命名为 Level\_03
   * 将预制件资源 Hat00 的 Addressable（可寻址）字段重命名为 Hat00
   * 将预制件资源 Hat01 的 Addressable（可寻址）字段重命名为 Hat01
   * 将预制件资源 Hat02 的 Addressable（可寻址）字段重命名为 Hat02
   * 将预制件资源 Hat03 的 Addressable（可寻址）字段重命名为 Hat03

## 配置相应的配置文件并构建 AssetBundles##generate-assetbundles-and-upload-content-manually

1. 在此阶段，创建一个新的 Addressables 配置文件，以便将与游戏开发相关的所有关联设置保存到此开发配置文件中：

   1. 单击 **Window（窗口）**> **Asset Management（资源管理）**> **Addressables** > **Groups（组）**。
   2. 从下拉选单中选择 **Profile（配置文件）**> **Manage Profiles（管理配置文件）**。
   3. 在打开的 Addressables Profiles（Addressables 配置文件）窗口中，选择 **Create（创建）**> **Profile（配置文件）**。
   4. 随即显示一个名为“New Profile”的配置文件。**右键单击**该配置文件，然后选择 **Rename Profile（重命名配置文件）**。将该配置文件命名为“Development Profile”。

2. 右键单击 **Development Profile** > **Set Active（设为激活状态）**。此操作会将 Development Profile 设置为当前正在使用的配置文件。

3. 现在，构建您的 [AssetBundle](https://docs.unity3d.com/Manual/AssetBundlesIntro.html)，这是一个存档文件，其中包含游戏的非代码资源。这样一来，编辑器的运行模式就会使用 AssetBundles 而不是本地资源。

   1. 单击 **Window（窗口）**> **Asset Management（资源管理）**> **Addressables** > **Groups（组）**。
   2. 从下拉选单中选择 **Build（构建）**> **New Build（新建构建）**> **Default Build Script（默认构建脚本）**。
   3. 从下拉选单中选择 **Play Mode Script（运行模式脚本）**> **Use Existing Build（使用现有构建）**。

## 开始使用 CCD##get-started-with-cloud-content-delivery

现在，您已准备好将此游戏连接到 Cloud Content Delivery (CCD) 服务，最终利用 Addressables 和 AssetBundles。CCD 是 Unity 的托管云服务，可用于托管内容并将其分发给应用程序在世界各地的用户，而无需重新安装应用程序新版本。

开始使用 CCD：

1. 转到 [Unity Dashboard（Unity 后台）](https://dashboard.unity3d.com/)。

2. 使用您的 Unity ID 登录。

3. 在 Projects（项目）下拉选单中，单击 **Create Project（创建项目）**。

   1. 将项目命名为“Loady Dungeons Workshop”。
   2. 单击 **Create project（创建项目）**。

4. 单击 **Loady Dungeons Workshop** 的 **Project Settings（项目设置）**（齿轮图标）。记下 Project ID。

5. 在左侧，选择 **Environments（环境）**。

6. 如果还没有开发环境，请创建一个。

7. 在 Dashboard（后台）登陆页面中，找到并选择 **Cloud Content Delivery**。

### 命令行界面（可选）##the-command-line-interface-optional

如果您更喜欢使用可选的命令行界面 (CLI) 来管理您的项目，请执行以下操作：

1. [下载](./cli.md#get-started)适用于您的操作系统的 CLI。
2. 确保将 CLI 的文件夹包含在计算机的环境变量中。
3. 打开命令行并导航到项目的文件夹。
4. 输入以下命令以确保 CLI 已成功配置：`ucd help`

请参阅 [CCD 命令行界面 (CLI)](./cli.md)。

## 存储桶##buckets

现在是时候创建存储桶来协助此项目的不同创建阶段了。

### 创建存储桶##create-buckets

1. 在 CCD 登陆页面中，单击左侧的 **Buckets（存储桶）**。

2. 从 Projects（项目）下拉选单中选择 **Loady Dungeons Workshop**（如果尚未选择）。

3. 单击 **Create Bucket（创建存储桶）**。

   1. 将存储桶命名为“Loady Dungeons Sample”。

   2. 为存储桶提供可选描述。

   3. 为此存储桶选择以下选项之一：

      * Open to all（向所有人开放）：任何人都可以修改此存储桶中的内容。
      * Promotion only（仅推进）：所有者和管理员可以通过[推进](./_index.md#release)来修改内容。任何人都无法将内容上传到此存储桶或删除此存储桶中的内容。

   4. 要限制对此存储桶的读取访问权限，请选择 **Enable Bucket Privacy（启用存储桶隐私）**。私有存储桶仅允许拥有访问令牌的用户读取内容。

      > **Note:**
      >
      > 创建存储桶后，无法更改存储桶隐私设置。

   5. 选择 **Next（下一步）**。

   6. 确保已检查生产环境和开发环境。

   7. 选择 **Create（创建）**。

Loady Dungeons Sample 存储桶现在应该显示在后台的 Cloud Content Delivery Buckets（Cloud Content Delivery 存储桶）页面上，对于开发环境和生产环境都是如此。您可以使用页面顶部的 Environments（环境）下拉选单来切换环境。记下这两个环境中存储桶的存储桶 ID，因为您稍后需要在远程加载路径中使用它们。

## 手动生成 AssetBundles 并上传内容##test-your-game

### 生成 AssetBundles##generate-assetbundles

[AssetBundle](https://docs.unity3d.com/Manual/AssetBundlesIntro.html) 是一个存档文件，其中包含 Unity 在运行时可以加载的特定于平台的非代码资源。

要生成 AssetBundles，请执行以下操作：

1. 在您的 Unity 编辑器项目中，单击 **Window（窗口）**> **Asset Management（资源管理）**> **Addressables** > **Groups（组）**。

2. 在 Profile（配置文件）下拉选单中，确保已选择 **Development Profile**。如果未选择，请现在选择。

3. 在 Profile（配置文件）下拉选单中，选择 **Manage Profiles（管理配置文件）**。

4. 选择 Development Profile 后，进行以下设置：

   * **RemoteBuildPath**：`AssetBundles/[BuildTarget]`，其中的 `[BuildTarget]` 是默认子文件夹。

   * **RemoteLoadPath**：`https://PROJECT_ID.client-api.unity3dusercontent.com/client_api/v1/buckets/BUCKET_ID/release_by_badge/latest/entry_by_path/content/?path=`

     * 将 `PROJECT_ID` 替换为您项目的 ID。如果您先前没有记下您的 Project ID，请通过以下方式进行查找：单击 Dashboard（后台）一角的用户名，然后单击 **Account（帐户）**> **Project Management（项目管理）**> **Loady Dungeons Workshop**。
     * 将路径中的 `BUCKET_ID` 替换为要使用的存储桶（在此示例中是您的开发环境中创建的 Loady Dungeons Sample 存储桶）的 ID。如果您先前没有记下此存储桶的 `BUCKET_ID`，请在 CCD Dashboard（CCD 后台）的存储桶列表中进行查找。
     * 路径中的 `latest` 指的是名为 [Latest（最新）](./_index.md#badge)的标示，这是分配给最新发布版本的自动生成的标示。

5. 返回到 Addressables Groups（Addressables 组）窗口。

6. 选择 **Hats**。

7. 在 Inspector（检视面板）中，设置：

   1. **Build Path（构建路径）**：RemoteBuildPath
   2. **Load Path（加载路径）**：RemoteLoadPath
   3. 对 Level 00、Level 01、Level 02 和 Level 03 重复上述设置

   此设置将这四组资源的构建路径和加载路径设置为我们为 Development Profile 指定的路径。

8. 仍在 Groups（组）窗口中，单击 **Build（构建）** 下拉选单，然后选择 **New Build（新建构建）**> **Default Build Script（默认构建脚本）**。此操作会将 AssetBundles 保存在 RemoteBuildPath 位置。

9. 要使用我们刚创建的构建作为游戏测试的基础，请单击 **Play Mode Script（运行模式脚本）**> **Use Existing Build（使用现有构建）**。

10. 单击 Unity 编辑器中的 **Play（运行）** 按钮以测试游戏。

    * 在游戏中按 **Start（开始）**。注意游戏现在的卡顿情况。

### 上传内容##uploading-the-content

此时，我们希望将此内容上传到我们先前在 CCD 中设置的 Development 存储桶中。

1. 从后台选择开发环境中的 Loady Dungeons Sample 存储桶。
2. 选择 **Upload using the dashboard（使用后台上传）**（如果存储桶为空）或 **Upload Content（上传内容）**（如果存储桶已包含条目）。
3. 进行拖放，或选择 **Browse（浏览）** 按钮，将内容从构建 AssetBundles 所在的文件夹上传到 CCD Development 存储桶。您的文件位于先前指定为 RemoteBuildPath 的文件夹中。
4. 选择 **Upload 5 Files（上传 5 个文件）**（四个关卡再加上 Hats）。
5. 上传过程完成后，选择 **Refresh Page（刷新页面）** 以更新存储桶信息的状态。相应条目将显示为 Unreleased Changes（未发布的更改）。这意味着这些条目存在于存储桶中，但尚未包含在[发布版本](./_index.md#release)中。
6. 要创建发布版本，请选择 **Create Release（创建发布版本）**。此操作会获取您上传到开发环境 Loady Dungeons Sample 存储桶的 AssetBundles，并将它们绑定到一个发布版本中。按照屏幕上的提示完成该过程。

请注意，CCD 会自动将自动创建的 `latest` 标示应用于此发布版本，并将此发布版本标记为在该存储桶中创建的最新发布版本。

> **Note:**
>
> 还可以[使用 CLI 上传内容](./cli.md)。

## 使用 CCD Management 包生成 AssetBundles 并上传内容

带有 Addressables 1.19.15+ 的 CCD Management 包可以方便构建、上传和发布可寻址内容。

> **Note:**
>
> 您需要通过 [Package Manager（包管理器）](https://docs.unity3d.com/Manual/upm-ui.html)升级 Addressables 版本并安装 CCD Management 包。
>
> 1. 选择 **Window（窗口）**> **Package Manager（包管理器）**。
> 2. 搜索 Addressables，选择版本 1.19.15+，然后选择 **Install（安装）**。
> 3. 搜索 CCD Management，选择版本 2.0.1+，然后选择 **Install（安装）**。

### 生成 AssetBundles##generate-assetbundles2

1. 在您的 Unity 编辑器项目中，单击 **Window（窗口）**> **Asset Management（资源管理）**> **Addressables** > **Groups（组）**。

2. 在 Profile（配置文件）下拉选单中，确保已选择 **Development Profile**。

3. 在 Profile（配置文件）下拉选单中，选择 **Manage Profiles（管理配置文件）**。

4. 在 Profiles（配置文件）窗口中，选择 **Development Profile**，然后更改 **Remote（远程）** 下拉选单以使用 **Cloud Content Delivery**。

   > **Note:**
   >
   > 此时，如果您尚未安装 CCD Management 包，Unity 编辑器会提示您添加此包。单击 **Install CCD Management SDK Package（安装 CCD Management SDK 包）** 按钮进行安装。

   1. 在下一个选项列表中，选择先前创建的 Loady Dungeons Sample 存储桶。
   2. 在随后出现的列表中，选择 Latest（最新）标示。

5. 返回到 Addressables Groups（Addressables 组）窗口。

6. 选择 **Hats**。

7. 在 Inspector（检视面板）面板的 **Content Packaging & Loading（内容打包和加载）** 下：

   1. 设置 **Build Path（构建路径）和 Load Path（加载路径）**：Remote（远程）
   2. 对 Level 00、Level 01、Level 02 和 Level 03 重复上述设置

   此设置将这四组资源的构建路径和加载路径设置为先前为 Development Profile 指定的路径对。如需了解更多有关路径对的信息，请参阅[配置文件](https://docs.unity3d.com/Packages/com.unity.addressables@latest/index.html?subfolder=/manual/AddressableAssetsProfiles.html)。

8. 在 Groups（组）窗口中，单击 Build（构建）下拉选单，然后选择 **New Build（新建构建）**> **Default Build Script（默认构建脚本）**。此操作会将 AssetBundles 保存在 RemoteBuildPath 位置。

9. 要使用我们创建的构建作为游戏测试的基础，请单击 **Play Mode Script（运行模式脚本）**> **Use Existing Build（使用现有构建）**。

10. 选择 Unity 编辑器中的 **Play（运行）** 按钮以测试游戏。

11. 在游戏中选择 **Start（开始）**。注意游戏现在的卡顿情况。

### 上传内容##uploading-the-content2

要生成、上传并发布此内容到我们先前在 CCD 中设置的 Loady Dungeons Sample 存储桶中，请执行以下操作：

1. 在您的 Unity 编辑器项目中，单击 **Window（窗口）**> **Asset Management（资源管理）**> **Addressables** > **Groups（组）**。
2. 选择 **Build & Release（构建并发布）**。

CCD Management 包会使用默认构建脚本行为来生成可寻址资源包。然后，此 Management 包会将与连接到 Loady Dungeons Sample 存储桶（以及我们先前设置的最新标示）的路径对相关联的所有组上传到这些远程目标。最后，此 Management 包会为这些远程目标创建一个发布版本，并将标示更新为 `latest`。

## 推进发布版本

将资源上传到开发环境中的 Loady Dungeons Sample 存储桶并将这些资源绑定到发布版本中之后，便可以将这些最新更改发布出来供公开使用。因此，我们还在您的生产环境中创建了此存储桶。生产环境中的存储桶包含可供玩家直接使用的发布版本。这意味着会通过称为[推进](./_index.md#buckets)的过程将发布版本从开发环境中的存储桶移动到生产环境中的存储桶。

要将发布版本从开发环境中的存储桶推进到生产环境中的存储桶，请执行以下操作：

1. 在 Unity Dashboard（Unity 后台）中转到 Loady Dungeons Workshop CCD 项目，确保在 Environments（环境）下拉选单中选择开发环境，然后选择 Loady Dungeons Sample 存储桶。
2. 选择 **Promote Release（推进发布版本）**。
3. 在 Target Environment（目标环境）下拉选单中，选择 **Production（生产）**。
4. 在 Target Bucket（目标存储桶）下拉选单中，选择 **Loady Dungeons Sample**。
5. 添加可选的发行说明。
6. 选择 **Next（下一步）**，然后按照屏幕上的提示进行操作。
7. 选择 **Promote Release（推进发布版本）**。

同样，请注意，CCD 会自动将自动创建的 `latest` 标示应用于此发布版本，并将此发布版本标记为在该存储桶中创建的最新发布版本。

在测试游戏之前，需要修改配置文件变量以指向正确的存储桶。有两种方法可以做到这一点：

1. 您可以为每个环境设置不同的玩家构建。您的开发构建将具有调试符号且 `bucket_id` 变量设置为开发环境中的存储桶，而您的生产构建将禁用调试符号且 `bucket_id` 变量设置为生产环境中的存储桶，但这两个构建将使用相同的内容。
2. 使用配置文件变量中的静态属性或 [TransformInternalId](https://docs.unity3d.com/Packages/com.unity.addressables@latest/index.html?subfolder=/api/UnityEngine.ResourceManagement.ResourceManager.TransformInternalId.html) 来动态更改目录在运行时访问的存储桶。如需详细了解 Addressables 中的静态配置文件变量和转换内部 ID，请参阅[转换资源 URL](https://docs.unity3d.com/Packages/com.unity.addressables@latest/index.html?subfolder=/manual/TransformInternalId.html)。

测试游戏：

1. 在 Unity 编辑器中，按编辑器的 **Play（运行）** 按钮。
2. 在游戏中按 **Start（开始）**。
3. 在游戏中按 **Play（运行）**。您现在可以在 Unity 编辑器中玩游戏。

现在，您已成功将发布版本及其所有资源从开发环境移动到生产环境，并已准备好部署到用户。

## 将 Addressables 与私有存储桶配合使用

要从私有存储桶读取数据，您需要拥有有效的存储桶访问令牌。

从 Addressables 1.19.4 开始，您可以使用 [WebRequestOverride](https://docs.unity3d.com/Packages/com.unity.addressables@latest/index.html?subfolder=/api/UnityEngine.AddressableAssets.Addressables.WebRequestOverride.html) 功能将存储桶访问令牌作为标头添加到请求中，如以下示例所示。

```plaintext
void Start()
{
	textComponent = GetComponent<Text>();
	Addressables.WebRequestOverride = webRequest =>
	{
		webRequest.SetRequestHeader("Authorization", "Basic "+token);
		//  Debug.Log($"Fetching: {webRequest.url}");
	};
	Addressables.LoadAssetAsync<TextAsset>("Assets/one.txt").Completed += handle =>
	{
		textComponent.text = handle.Result.text;
		// Debug.Log($"Text is now: {handle.Result.text}");
	};
}
```

在此示例中，`token` 是采用 base64 编码的存储桶访问令牌值。
