# 将 UDP 与其他服务结合使用

> Learn how the Unity Distribution Portal worked with other services, for a service that shut down in February 2025.

| **重要提示**                                                                                                                                                                                                                                                                                                 |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Unity Distribution Portal (UDP) 将于 2025 年 2 月 17 日关闭。自该日起，Unity Distribution Portal (UDP) 网页控制台及相关服务将永久停用。要下载密钥库以及如何将游戏直接重新发布到应用商店的说明，请访问 [UDP 概述](https://api-udp.unity.com/overview)页面。如果您对帐户有任何疑问，请向 [Unity 客户支持](https://support.unity.com/hc/en-us/requests/new?ticket_form_id=360000323692)部门提交工单。 |

## UDP 构建中的 Google Play 游戏服务

### 概述

通过在您的 Android 游戏中实施 [Google Play 游戏服务](https://developers.google.com/games/services/console/enabling)，您可以利用 Google 的服务层获得成就和排行榜等功能。如果您的游戏实施 Google Play 游戏服务，需进行额外配置以支持 [UDP](https://unity.com/products/unity-distribution-portal) 为不同的商店创建的构建。

当您的游戏调用 Google Play 游戏服务时，Google Play 游戏服务会检查以下详细信息是否与在 Google Play 管理中心上注册的信息相匹配：

* 应用程序的**包名称**
* 为该应用程序签名所使用的**证书**

如果不匹配，玩家将无法使用 Google Play 游戏服务登录应用程序。

对于您通过 UDP 发布游戏的某些商店，UDP 会向包名称添加商店特定的后缀。此外，如果您不使用自己的私钥生成证书，UDP 将为每个重新打包的构建生成一个证书。这些事件会导致您的证书和/或包名称不再与 Google Play 管理中心上的信息匹配。这将阻止用户使用 Google Play 游戏服务登录游戏。

以下部分说明如何解决此问题。

### 为 UDP 构建配置 Google Play 游戏服务

本节说明如何将您的 UDP 版本链接到 Google Play 应用程序，以便 Google Play 游戏服务可以在所有这些应用程序上运行。

1. 在 Google Play 管理中心中，转到目标应用。

2. 转到**Play 游戏服务 (Play Games Services)** > **设置和管理 (Setup and management)** > **配置 (Configuration)**。

   * 如果您的 Google Play 游戏实施了 Google Play 游戏服务，则您的游戏将已链接到 Google Play 游戏服务项目。在这种情况下：

     1. 选择**使用现有的 Play 游戏服务项目 (Use an existing Play Games Services project)**。
     2. 选择您的游戏项目并选择**使用 (Use)**。
     3. 按照[将 UDP 应用链接到您的游戏服务](#link)中的步骤操作。

   * 如果您的 Google Play 游戏未实施 Google Play 游戏服务：

     1. 在 Play 游戏服务 (Play Games Services) 设置页面中，选择**是，我的游戏已经使用了 Google API (Yes, my game already uses Google APIs)** 或者**否，我的游戏不使用 Google API (No, my game doesn’t use Google APIs)**。
     2. 按照[创建和链接 Google Play 游戏服务项目](#create)中的步骤操作。

#### 创建和链接 Google Play 游戏服务项目

本节介绍如何创建 Google Play 游戏服务项目并将其链接到新的或现有的云项目。

如果您在 Play 游戏服务 (Play Games Services) 设置页面中选择了**是，我的游戏已经使用了 Google API (Yes, my game already uses Google APIs)**：

1. 选择一个云项目。
2. 选择使用 (Use) 以创建新的 Play 游戏服务项目并将其链接到您现有的云项目。

如果您在 Play 游戏服务 (Play Games Services) 设置页面中选择了**否，我的游戏不使用 Google API (No, my game doesn’t use Google APIs)**：

1. 输入游戏名称。
2. 选择创建 (Create) 以创建新的 Play 游戏服务项目并将其链接到新的云项目。

当您创建新的 Play 游戏服务项目时，**添加凭据**链接被禁用。

1. 选择**配置 OAuth 同意屏幕 (Configure OAuth consent screen)**。

2. 在 Play 游戏服务 (Play Games Services) 配置页面中，选择刷新 (Refresh) 。

   现在已启用添加凭据 (Add credential) 选项。

3. 选择**添加凭据 (Add credential)**。

   这会打开添加凭据 (Add credential) 页面。

4. 在添加凭据 (Add credential) 页面中：

   1. 选择 **Android** 作为**类型** 。
   2. 将**启用反盗版 (Enable anti-piracy)** 设置为**关闭 (Off)**。这允许用户访问您的游戏，前提是用户安装自 Google Play 以外的其他应用商店。
   3. 在授权 (Authorization) 部分，选择**创建 OAuth 客户端 (Create OAuth client)**。这会打开一个弹出窗口。
   4. 选择**创建 OAuth 客户端 ID (Create OAuth Client ID)** 并使用弹出窗口中的详细信息来完成表单。

完成上述步骤后，您的 Google Play 游戏就会链接到其 Google Play 游戏服务。下一步是[将您的 UDP 构建链接到游戏服务](#link)。

#### 将 UDP 应用链接到您的游戏服务

将应用链接到 Google Play 游戏服务后，您可以将其他 (UDP) 应用链接到游戏服务。

1. 在 Google Play 管理中心中，选择 **Play 游戏服务 (Play Games Services)** > **设置和管理 (Setup and management)** > **配置 (Configuration)**。
   1. 在Play 游戏服务 (Play Games Services) 配置页面中，选择**添加凭据 (Add credential)**。

2. 在添加凭据 (Add credential) 页面中：

   1. 选择 **Android**。
   2. 将**启用反盗版 (Enable anti-piracy) 设置为关闭 (Off)**。这允许用户访问您的游戏，前提是用户安装自 Google Play 以外的其他应用商店。
   3. 在**授权 (Authorization)** 部分，选择**创建 OAuth 客户端 (Create OAuth client)**。这会打开一个弹出窗口。
   4. 选择**创建 OAuth 客户端 ID (Create OAuth Client ID)** 并使用弹出窗口中的详细信息来完成表单。

3. 在创建 OAuth 客户端 ID (Create OAuth client ID ) 表单中，输入所需的详细信息，为您的 UDP 构建之一创建条目。

   1. 在**名称 (Name)** 字段中，以相应的商店命名构建，例如“Samsung version”。

   2. 在**包名称 (Package name)** 字段中，指定通过 UDP 控制台向相应商店注册的构建的包名称。

      特定于商店的包名称显示在 UDP 控制台中：

      1. 转到我的游戏 (My Games) > 发布 (Publish) 选项卡。
      2. 选择相应商店的\*\*高级 (Advanced)\*\*设置。

         包名称显示在基本信息 (Basic Information) 部分中。

   3. 在证书字段中，使用对应 UDP 商店所使用的证书。在重新打包操作完成后，UDP 会使用新证书对应用程序进行签名。

      特定于商店的证书显示在 UDP 控制台中：

      1. 转到我的游戏 (My Games) > 发布 (Publish) 选项卡。
      2. 选择相应商店的\*\*高级 (Advanced)\*\*设置。

         证书显示在基本信息 (Basic Information) 部分中。

         **注意**：您还可以下载 APK 证书并通过以下命令获取指纹信息：

         `openssl x509 -in [downloaded-pem-filepath] -fingerprint -noout`
      3. 将 SHA-1 从 UDP 控制台复制到证书字段中。

4. 完成表格后，选择**创建 (Create)** 并返回 Google Play 管理中心。

5. 选择**刷新 OAuth 客户端 (Refresh OAuth clients)**。

6. 选择您的新 OAuth 客户端。
   1. 选择**保存更改 (Save changes)** 以保存凭据。

7. 对要链接到 Google Play 应用程序的每个特定于商店的 UDP 构建重复上述步骤。

您可以在 Google 云平台 (Google Cloud Platform) > Google API 和服务 (Google API & Services) 控制面板的凭据 (Credentials) 下查看已链接到 Google Play 应用程序的 UDP 构建。

这些步骤使 Google Play 游戏服务能够在所有以这种方式链接的 UDP 商店版本上成功运行，不包括 Mi GetApps（其 SDK 集成了旧版本的 Google 移动服务，这会产生冲突）。

**注意**：对 Google 系统的任何更改都可能影响上述解决方案。有关 Google 故障排除信息的更多信息，请参阅 [Google 文档](https://www.google.com/url?q=https://developers.google.com/games/services/android/troubleshooting\&sa=D\&ust=1611571996561000\&usg=AOvVaw00u3uXWmm9qmGpqo4yuFQX)。

## 将 Build Automation 与 UDP 结合使用

还可以使用 [Build Automation](https://docs.unity.com/ugs/en-us/manual/devops/manual/unity-build-automation.md) 通过以下方式将游戏部署到 UDP 控制台：

* [将 APK 上传到 Build Automation](#upload)，然后从那里部署到 UDP
* [使用 Build Automation 构建游戏](#build)，然后从那里部署到 UDP

## 通过 Build Automation 将构建推送到 UDP 控制台

本节介绍如何使用 Build Automation 将游戏推送到 UDP。在 Unity 编辑器中，在项目设置 (Project Settings) 窗口中启用 Build Automation。

### 在编辑器中使用 Build Automation 将游戏部署到 UDP

要通过 Unity 编辑器中的 Build Automation 功能将游戏部署到 UDP，您需要上传 UDP 构建版本并将其推送到 UDP。

1. 在项目设置 (Project Settings) 窗口的 **Build Automation** 选项卡中，如果先前从未上传过任何构建版本，请选择**上传构建 (Upload Build)**。

2. 在**FILE** 中：

   * 选择 UDP 构建版本的 APK
   * 在 **LABEL** 中输入有用的标签
   * 将**平台 (PLATFORM)** 字段设置为 Android。

3. 选择 **UPLOAD**，然后等待完成上传过程。

4. 在项目设置 (Project Settings) 窗口的 **Build Automation** 选项卡中，根据构建的**历史 (History)** 时间轴找到所需的构建版本，然后选择 **推送到 Unity Distribution Portal (Push to Unity Distribution Portal)**。
   1. 确认想要推送，然后确认操作完成。

### 使用 Unity Dashboard 将游戏部署到 UDP

要通过 Unity Dashboard 中的 Build Automation 功能将游戏部署到 UDP，您需要将 UDP 构建版本上传到 Unity Dashboard 并从其中推送到 UDP。

1. 在 [Unity 开发者控制面板 (Unity Developer Dashboard)](https://developer.cloud.unity3d.com/build) 中，导航到项目的 **Build Automation** > **历史 (History)**。
2. 选择 **上传 (Upload)**，然后选择 APK 文件。
3. 在**平台 (Platform)** 字段中，选择 **Android**。
4. 选择**上传 (Upload)**。
5. 选择构建版本旁边的更多 (More) 菜单以展开下拉菜单。
6. 选择**推送到 Unity Distribution Portal (Push to Unity Distribution Portal)**。

## 通过 Build Automation 进行构建和部署

如果使用 Unity Teams Advanced，那么可以[自动生成构建](https://docs.unity.com/ugs/en-us/manual/devops/manual/unity-build-automation.md#continuous-integration)。

在项目设置 (Project Settings) 窗口的 Build Automation 选项卡中：

1. 选择**管理构建目标 (Manage Build Targets)** > **添加新的构建目标 (Add new build target)**
2. 在**目标设置 (TARGET SETUP)** 窗口中，将**平台 (PLATFORM)** 字段设置为 Android 并输入有用的**目标标签 (TARGET LABEL)**。
3. 选择**下一步 (Next)：保存 (Save)**。
4. 选择**启动 Build Automation (Start Build Automation)**，然后选择刚才创建的目标构建。

通过 Unity Build Automation 开发者控制面板 (Developer Dashboard) 将构建版本直接推送到 UDP（如上所示）。

## 服务互操作性

UDP 可以让游戏使用的其他服务了解该游戏是从哪个商店下载的。

Unity 服务以及第三方服务或您自己的服务可以多种方式使用这一信息。

例如，在使用 [Unity Remote Config](https://unity.com/remote-config) 时，您可以根据定义的规则（例如，从哪个商店下载的游戏）来调整游戏设置。

本节介绍如何让其他服务访问此信息，并提供了一个[示例](#example)。

### 工作原理

当游戏首次在玩家的设备上启动时，UDP 将创建 `udp.json` 文件并将其放入游戏的持久数据路径中。此文件包含的字段 `udpStore`，这会显示游戏是从哪个商店下载的。提取该信息根据需要进行使用。

\*\*注意：\*\*这不会在游戏清单中添加任何新的权限。

### 定位 udp.json

文件 `udp.json` 保存在：

`Application.PersistentDataPath + '/Unity' + /Application.CloudProjectID + /udp/udp.json`

其中：

* `Application.PersistentDataPath` 是游戏的持久数据路径
* `Application.CloudProjectID` 是游戏的 Unity 项目 ID

以下是一个 `udp.json` 文件路径示例：

`path/storage/emulated/0/Android/data/com.mystudio.mygame/files/Unity/c83d2de2-de74-4b75-83fc-ade948bda064/udp/udp.json`

其中：

* `Application.PersistentDataPath`= `path/storage/emulated/0/Android/data/com.mystudio.mygame`
* `Application.CloudProjectID`= `c83d2de2-de74-4b75-83fc-ade948bda064`

### 读取 udp.json

文件 `udp.json` 包含以下信息：

```
{"key":"UDP","udpStore":"StoreName","udpClientId":"value_of_udpClientId","CloudProjectId":"value_of_CloudProjectId"}
```

字段 `udpStore` 包含的值就是下载游戏的 UDP 商店。

以下是一个 `udp.json` 文件示例：

```
{"key":"UDP","udpStore":"Huawei","udpClientId":"icjaB7wmu_q7AOjrSLH8yw","cloudProjectId":"bc2be074-09f3-450f-8e98-a0f79c9746f7"}
```

在此示例中，游戏是从 HUAWEI AppGallery下载的。

\*\*提示：\*\*使用 `JSONUtility.FromJsonOverwrite` 可将文件内容作为文本资源读取。

### udpStore 值

下表列出了 UDP 商店可能的 `udpStore` 值。

这些值区分大小写。

| 商店（UDP 上的通道名称）              | udpStore 的值 |
| --------------------------- | ----------- |
| UDP Sandbox（适用于通用 UDP 构建版本） | UdpSandbox  |
| ONE store                   | OneStore    |
| APPTUTTi                    | Apptutti    |
| Mi GetApps (Xiaomi)         | XiaomiStore |
| HUAWEI AppGallery           | Huawei      |
| QooApp Game Store           | QooApp      |
| Uptodown                    | Uptodown    |
| SHAREit                     | ShareIt     |
| JioGames                    | JioGames    |
| Legion Store                | Legion      |

### 将 udpStore 与 Remote Config 一起使用

使用 [Unity Remote Config](https://unity.com/remote-config) 可以在不部署应用程序新版本的情况下优化游戏设置。当玩家启动游戏时，Remote Config 会检测用作规则条件的上下文属性（基于 Unity、应用程序、用户或您定义的自定义条件）。然后，相应服务会根据适用于每个玩家的规则为玩家返回自定义设置。

在规则条件中使用 `udpStore` 作为属性，就可以根据游戏是从哪个 UDP 商店下载的来确定游戏设置。

要使用 Remote Config 实现 udpStore，请遵循以下步骤。

1. 下载并安装 UDP 包。
2. 下载并安装 Unity Remote Config 包。请参阅 [Remote Config 文档](https://docs.unity3d.com/Packages/com.unity.remote-config@latest/index.html)。
3. 创建一个 AppAttributes 结构，其中至少包含参数“udpStore”：
   ```
   public struct AppAttributes
   {
     public string udpStore;
   }
   ```
4. 在游戏代码中，实现 Remote Config ConfigManager.FetchConfigs 调用。
5. 当调用 FetchConfigs 时，创建一个AppAttributes 结构的新实例，从以下位置读取 UDP 商店数据文件：Application.PersistentDataPath + '/Unity' + /Application.CloudProjectId + /udp/udp.json 使用 JSONUtility.FromJsonOverwrite 可将文件内容作为文本资源读取。
   ```
   {
       string udpFilePath = System.IO.Path.Combine(Application.persistentDataPath, "Unity", Application.cloudProjectId, "udp", "udp.json");
       string udpFileContents = System.IO.File.ReadAllText(udpFilePath);
       var appAttr = JsonUtility.FromJson&lt;AppAttributes&gt;(udpFileContents);
       Unity.RemoteConfig.ConfigManager.FetchCompleted += ConfigManager_FetchCompleted;
       Unity.RemoteConfig.ConfigManager.FetchConfigs(null, appAttr);
   }
   ```
6. 确保在 ConfigManager.FetchConfigs 中使用 AppAttributes 结构。
7. 打开 **Remote Config** 设置（**服务 (Services)** > **Remote Config** > **配置 (Configure)**)，然后创建需要根据 UDP 商店而改变的参数。
8. 设置好参数并插入到游戏代码中后，请在 Remote Config 窗口中为每个商店创建一个规则。
9. 在每个规则的条件中，放入：app.udpStore == "\[storeName]"
   * 请参阅 [udpStore 的值](#udp-values)


     **Frame:**
     ![](/api/media?file=/engine/6000.0/media/images/UDPServiceInteroperability_01.png)
10. 要启用相应的设置，请在 Remote Config 设置的左面板上选中规则名称旁边的复选框。
11. 针对设备构建应用程序，并确保正确应用规则，然后发布。

## 使用 Unity IAP 实现用于 UDP 的 IAP 商品

如果要使用 Unity IAP 实现 UDP，请先[设置 Unity IAP](https://docs.unity3d.com/Manual/UnityIAPSettingUp.html)。

**注意**：如果选择使用 Unity IAP 版本 1.22.0-1.23.5 来实现 UDP（而不是使用 UDP 包），则仅通过 Unity IAP 实现即可。

Unity IAP 自动进行以下处理：

* 初始化 UDP
* 查询商店的 IAP 商品库存
* 请求购买某个商品
* 消耗所购买的商品

但是，您的游戏必须根据 [Unity IAP 文档](https://docs.unity3d.com/Manual/UnityIAP.html)正确使用 Unity IAP 的类似功能（例如初始化和购买）。

使用 Unity IAP 实现游戏的应用内购后，请按照以下步骤使用 Unity IAP 设置 UDP。

### 查询 IAP 库存

#### 使用 Unity IAP（代码实现）

##### 获取编辑器中定义的 IAP 商品

在获取要传递给 `queryInventory` 方法的 IAP 商品时，请调用 `ProductCatalog.LoadDefaultCatalog()`。此时会返回编辑器的 **IAP 目录 (IAP Catalog)**（**服务 (Services)** > **Unity IAP** > **IAP 目录 (IAP Catalog)**）中定义的 IAP 商品。

例如：

```
var catalog = ProductCatalog.LoadDefaultCatalog();

foreach (var product in catalog.allValidProducts)
{
   if (product.allStoreIDs.Count > 0)
   {
       var ids = new IDs();
       foreach (var storeID in product.allStoreIDs)
       {
           ids.Add(storeID.id, storeID.store);
       }
       builder.AddProduct(product.id, product.type, ids);
   }
   else
   {
       builder.AddProduct(product.id, product.type);
   }
}
```

##### 从 UDP 控制台获取 IAP 商品信息

如果您打算在 UDP 控制台上修改游戏的 IAP 目录，请准备好游戏以便从 UDP 控制台获取 IAP 商品信息。

在获取 IAP 商品以便传递给 `queryInventory` 方法时，请调用 builder.AddProduct 以获取 UDP 控制台上定义的特定 IAP 商品：

`builder.AddProduct(product.id, product.type, new IDs{})`

要显示带有货币格式的商品价格，请使用 `productInfo.Value.Price`。

##### 从 UDP 控制台获取 IAP 目录

要获取在 UDP 控制台上定义的所有 IAP 商品，请不要调用任何 IAP 商品检索方法。游戏随后将从 UDP 控制台获取整个 IAP 目录。

注意：将 IAP 商品的 CSV 文件上传到 UDP 控制台上会完全覆盖您的 IAP 目录。

#### 使用 Unity IAP 包填充 IAP 目录

在 [IAP 目录](/engine/6000.0/manual/unity-services/udp.md#iap-catalog)中添加和配置 UDP 应用内购。

**注意**：如果未在游戏客户端中使用 IAP 目录（例如，如果仅在游戏服务器上维护 IAP 商品），仍必须[在 UDP 控制台上创建 IAP 目录](/engine/6000.0/manual/unity-services/udp/implementing-iap.md#create)。

1. 在 Unity 编辑器中，选择**服务 (Services)** > **Unity IAP** > **IAP 目录 (IAP Catalog)**。
2. 选择**添加产品 (Add Product)**，然后输入每个 IAP 商品的详细信息。
   1. 在 Unity Distribution Portal 配置 (Unity Distribution Portal Configuration) 下添加 IAP 商品的价格。
      **Frame:**
      ![](/api/media?file=/engine/6000.0/media/images/UDPGamesWithIAP_09.png)
3. 要将 IAP 商品保存到 UDP 控制台，请选择**同步到 UDP (Sync to UDP)**。对所创建的每个 IAP 商品执行此操作。

为了确保正确保存了 IAP 目录，请检查 UDP 控制台中是否显示了所添加的商品。
