# 游戏覆盖和 Settings

> Configure Game Overrides and settings in Remote Config.

Unity Remote Config 使用\_\_游戏覆盖\_\_（之前称为\_\_广告系列\_\_）来定向到特定用户群体并向不同的群体提供不同的设置。游戏覆盖与 **Settings** 关联。您需将 Settings 映射到游戏代码中的变量，从而在满足游戏覆盖的受众条件时覆盖其默认值。

您可以在设计游戏时或开始新的部署之前提早规划 Remote Config 设置。Unity 建议在初始部署中包含不活跃的 Remote Config 设置，以便您可以稍后在了解受众如何使用您的游戏以及在不同设备上的效果后应用这些设置。

在 Unity 编辑器中，选择 **Window（窗口）**> **Remote Config**，打开 **Remote Config** 窗口即可开始进行 Settings 相关操作。


**Frame:**
![在 Unity 编辑器中导航到 Remote Config 窗口。](/api/media?file=/remote-config/media/images/rc-management-window.png)

您可以使用 **Remote Config** 窗口来配置 Remote Config 设置。游戏覆盖可以在 Web Dashboard（Web 控制面板）中配置。该控制面板可通过 \*\*Open Dashboard（打开控制面板）\*\*按钮打开。游戏覆盖决定了使用 Settings 需满足的条件或玩家细分段。默认情况下，您可以从 **Settings Config** 开始入手。此配置包含所有用户都会收到的默认 Settings，除非应用了一个具有[更高优先级](#prioritizing-game-overrides)的活跃游戏覆盖。

**重要提示**：每个[环境](./configuring-your-project.md#remote-config-environments)都有一个唯一的游戏覆盖集。在为您的游戏配置游戏覆盖之前，请确保在 **Remote Config** 窗口中选择正确的 Remote Config 环境。

一个 Settings 就是一个键值对。您可以将键名映射到游戏代码中的变量，这样您无需更改代码即可动态更改其值。

## 添加新的 Settings##adding-new-settings

默认的 **Settings Config** 配置包含您为给定环境创建的所有 Settings。要创建新的 Settings，请高亮显示 **Settings Config** 配置，然后单击右侧面板底部的 \*\*Add Setting（添加设置）\*\*按钮。

**注意**：鉴于游戏代码可以在编辑器中使用 Settings，因此必须在编辑器中创建 Settings。不过，在游戏二进制文件中创建 Settings 后，也可以使用 Remote Config REST API 或 Remote Config Web 控制面板对其进行更新。有关更多信息，请参阅[界面](./_index.md#remote-config-interfaces)。

每个 Settings 都包含 **Key**、**Type** 和 **Value**：

| **参数**    | **描述**                                                                                                                                                                                                                         | **示例**                                                                                                         |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| **Key**   | Settings 的名称，必须符合以下游戏覆盖的规定：必须在其环境中是唯一的。必须以字母开头。只能包含字母、数字、句点、下划线或连字符。不得超过 255 个字符。                                                                                                                                              | `enemyHealth``eventPackPrice``enableBetaFeature`                                                               |
| **Type**  | Settings 值的 C# 变量数据类型。受支持的类型包括：`Int``Float``Bool``String``Long``Json`                                                                                                                                                          | `int``float``bool``string``long``json`                                                                         |
| **Value** | 此 Settings 的值，必须符合以下游戏覆盖的规定：整型值为 32 位整数（–2147483648 至 2147483647）。浮点值为单精度、32 位浮点数。字符串限制为 10000 个字符。布尔值只能为 true 或 false。长整值为 64 位带符号整数（-9,223,372,036,854,775,808 至 9,223,372,036,854,775,807）。Json 值为 ECMA-404 标准支持的任何有效 json。 | `100``4.99``true``‘jack-o-lantern’``123456789012345``{"jsonKey1": {"jsonSubKey1": "on","jsonSubKey2": "off"}}` |


**Frame:**
![Settings 参数示例。](/api/media?file=/remote-config/media/images/settings-params-with-json.png)

## 添加新的游戏覆盖##adding-new-game-overrides

要创建新的 Remote Config 游戏覆盖，请单击 \*\*Open Dashboard（打开控制面板）\*\*按钮，打开您的 Web 浏览器并跳转到 Remote Config 页面，然后依次单击 \*\*View Overrides（查看覆盖）\*\*按钮和 **Create Override（创建覆盖）**。每个游戏覆盖均包含五个参数，详见下文：

* [名称](#name)
* [定向策略](#targeting-strategy)
* [条件](#condition)
* [部署比例](#rollout-percentage)
* [内容类型](#content-type)
* [起始日期和时间](#start-date-and-time)
* [结束日期和时间](#end-date-and-time)

### 名称##name

**名称**是指游戏覆盖的名称。例如，您可以将难度曲线的游戏覆盖命名为 `level_1_enemies`，或者将季节性活动的游戏覆盖命名为 `halloween_event`。

### 定向策略##targeting-strategy

**定向策略**定义游戏覆盖的受众类型。该策略可以是 `Stateful`，此时您可以选择 All Spenders（所有消费玩家）或 Existing Players（现有玩家）等受众；该策略也可以是 `Stateless`，此时您可以根据 `Condition` 定义目标受众。

### 条件##condition

**条件**是上下文数据属性的 JEXL 表达式（请参阅下文的 **JEXL 支持**部分），用于定义要将游戏覆盖应用到的受众。您可以使用多个标准来定义此细分段。Remote Config 目前支持三个属性类别：

* **用户**类别包含由开发者定义用于描述用户（例如，订阅状态、姓名、年龄）的自定义属性，您必须将其传递给 [RemoteConfigService.Instance.FetchConfigs\<T, T2>(T userAttributes, T2 appAttributes)](https://docs.unity3d.com/Packages/com.unity.remote-config-runtime@latest/index.html?subfolder=/api/Unity.Services.RemoteConfig.RemoteConfigService.html#Unity_Services_RemoteConfig_RemoteConfigService_FetchConfigs__2___0___1_)。

  \*\*注意：\*\*使用 `SetCustomUserId` 时，您传递的 ID 会自动作为 `customUserId` 附加到您的 `user` 属性。

* **应用**类别包含由开发者定义用于描述应用程序（例如，连接状态、应用程序版本、当前等级）的自定义属性，您必须将其传递给 [RemoteConfigService.Instance.FetchConfigs\<T, T2>(T userAttributes, T2 appAttributes)](https://docs.unity3d.com/Packages/com.unity.remote-config-runtime@latest/index.html?subfolder=/api/Unity.Services.RemoteConfig.RemoteConfigService.html#Unity_Services_RemoteConfig_RemoteConfigService_FetchConfigs__2___0___1_)。

* **unity** 类别包含预定义的属性，详见下表：

| **属性**                       | **描述**                                                                                                                                             | **示例**                                                           |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `unity.appBuildVersion`      | 应用程序所运行的版本号（在编辑器中，通过转到 **Edit（编辑）**> **Project Settings（项目设置）**> \*\*Player（玩家）\*\*来设置此属性）。                                                        | `unity.appBuildVersion == '1'`                                   |
| `unity.appVersion`           | 应用程序所运行的发布版本（在编辑器中，通过转到 **Edit（编辑）**> **Project Settings（项目设置）**> \*\*Player（玩家）\*\*来设置此属性）。                                                       | `unity.appVersion == '1.0'`                                      |
| `unity.cpu`                  | CPU 处理器的名称。                                                                                                                                        | `unity.cpu == 'Intel(R) Core(TM) i7-7920 HQ CPU @ 3.10GHz'`      |
| `unity.cpuFrequency`         | 运行您的应用程序的设备的处理器频率，以 MHz 为单位。                                                                                                                       | `unity.cpuFrequency >= 3100`                                     |
| `unity.country`              | 适用的国家/地区。此属性使用 [ISO 3166-1 alpha2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) 国家/地区代码。有关如何定义自定义属性的信息，请参阅关于[代码集成](./code-integration.md)的文档。 | `unity.country == 'US'`                                          |
| `unity.language`             | 适用的语言。此属性使用 [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) 语言代码。有关如何定义自定义属性的信息，请参阅关于[代码集成](./code-integration.md)的文档。          | `unity.language == 'en'`                                         |
| `unity.osVersion`            | 运行您的应用程序的设备的操作系统版本。                                                                                                                                | `unity.osVersion == 'Mac OS X 10.14.4'`                          |
| `unity.platform`             | 适用的设备或平台。以下值有效：`Android``iOS``Linux``macOS``PS4``PS5``Switch``WebGL``Wii``Windows``XboxOne``XboxSeriesS``XboxSeriesX`                              | `unity.platform == 'iOS'`                                        |
| `unity.timeSinceStart`       | 自应用程序会话开始后经过的时间，以毫秒为单位。                                                                                                                            | `unity.timeSinceStart >= 60000`                                  |
| `unity.graphicsDeviceVendor` | 用户显卡的供应商。                                                                                                                                          | `unity.graphicsDeviceVendor == 'ATI Technologies Inc.'`          |
| `unity.ram`                  | 设备上 RAM 内存的大小，以 MB 为单位。                                                                                                                            | `unity.ram >= 16384`                                             |
| `unity.model`                | 设备的型号。                                                                                                                                             | `unity.model == "LGE Nexus 5"` 或 `unity.model.contains("Nexus")` |

**注意**：列出的 `unity` 属性有可能发生更改。如需更新后的完整列表，请参阅 [REST API 文档](https://services.docs.unity.com/remote-config-admin/v1/#tag/Game-Overrides)。

例如，如果您想要定义以得分超过 10 的用户为目标受众的游戏覆盖，可以使用点符号从 `app` 上下文定义一个 `score` 属性：

```text
app.score >= 10
```

您还可以在一个游戏覆盖中引用多个属性：

```text
user.score >= 10 && app.level == 5
```

要定义符合所有条件并始终应用的游戏覆盖，只需输入 `true` 即可。

#### JEXL 支持##jexl-support

Remote Config 支持 [Java 表达式语言 (JEXL) 规范](http://commons.apache.org/proper/commons-jexl/reference/syntax.html)，但存在一些例外情况：

* Remote Config 仅支持表达式。
* Remote Config 不支持脚本。
* Remote Config 目前不支持函数和条件。
* 尽管 Remote Config 支持使用 `&&` 和 `||` 语句来设置多个条件，但 JEXL 字符串不能超过 500 个字符。

**注意**：不能嵌套属性（例如 `app.level1.score`）。如果使用无效的 JEXL 字符串或将 **Condition（条件）** 字段留空，则会导致错误。

### 部署比例##rollout-percentage

部署比例决定将遵循此游戏覆盖的用户群所占的百分比。如果值小于 100，Unity 会根据用户 ID 将该游戏覆盖随机分配给该比例的玩家。虽然不同玩家的体验可能有所不同，但每个玩家都将在各个游戏会话中获得一致的体验。与分析功能结合使用来解析结果时，此参数尤其有用。

### 内容类型##content-type

您可以根据使用的服务为特定的游戏覆盖选择多种类型的内容，比如，Remote Config 中使用的 `Config Overrides`，或者 Economy 服务中使用的 `Currency` 或 `Inventor Item` 等其他内容。

### 起始日期和时间##start-date-and-time

您可以选择指定起始日期和时间，即游戏覆盖的生效时间。时间戳以 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) UTC 格式 (`YYYY-MM-DDThh:mm:ssZ`) 的字符串形式表示。如果您未指定值，则游戏覆盖会在[激活](#enabling-and-disabling-game-overrides)后立即生效。

### 结束日期和时间##end-date-and-time

您可以选择指定结束日期和时间，即游戏覆盖的失效时间。时间戳以 [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) UTC 格式 (`YYYY-MM-DDThh:mm:ssZ`) 的字符串形式表示。如果您未指定值，则游戏覆盖会在您将其[停用](#enabling-and-disabling-game-overrides)之前持续有效。

## 将 Settings 应用到游戏覆盖##applying-settings-to-a-game-override

要将 Settings 应用到游戏覆盖，请导航到所需的游戏覆盖并**编辑** **Content（内容）** 代码块以查看所有可用 Settings 的列表。

## 启用和禁用游戏覆盖##enabling-and-disabling-game-overrides

使用 Game Override（游戏覆盖）页面顶部的按钮即可启用或禁用游戏覆盖。

## 在编辑器窗口中编辑 Settings##editing-settings-in-the-editor-window

要在编辑器的 Remote Config 窗口中编辑 Settings 的键和值，请确保保存并**推送**更改。完成该操作之前，您的配置仅储存在本地。请确保先推送更改来进行保存，然后再切换 Remote Config 环境。

您可以通过单击要删除的相应元素旁边的 \*\*trashcan（回收站）\*\*按钮来删除 Settings。请注意，如果活跃的游戏覆盖当前正在使用某个 Settings，则不应删除该 Settings。

## 确定游戏覆盖的优先级##prioritizing-game-overrides

您可以为每个游戏覆盖分配一个加权优先级值，包括 `Low`、`Medium` 或 `High`。如果您想要以数字形式分配优先级值，可以通过高级编辑器在 `1`（最高优先级）和 `1000`（最低优先级）之间进行设置。为此，请单击 **Edit Schedule（编辑计划）**-> \*\*Scheduling（排期）\*\*字段（位于游戏覆盖中），然后选择 \*\*Use Advanced Editor（使用高级编辑器）\*\*并输入一个整数值。

* 新的游戏覆盖和 **Settings Config** 配置默认为 `medium`。
* 当发生冲突时，则先创建的游戏覆盖优先分配优先级。

## 更新游戏覆盖和 Settings##updating-game-overrides-and-settings

要编辑游戏覆盖并保存您的更改，请执行以下操作：

1. [禁用](#enabling-and-disabling-game-overrides)游戏覆盖。
2. 在编辑器窗口或 WebUI 中编辑所需的键值字段。
3. 单击 \*\*Push（推送）\*\*按钮以将更改保存到远程服务。
4. 单击 \*\*Pull（拉取）\*\*按钮来从服务检索最新的远程设置。
   1. 确认更新已应用。
5. [启用](#enabling-and-disabling-game-overrides)游戏覆盖。
   1. 再次拉取以确认游戏覆盖已正确更新并生效。

**注意**：将远程更改拉取到您的本地配置时，从服务检索的设置会覆盖并删除您的本地设置。

## JSON 设置值##json-setting-value

如果您使用的是 JSON 类型的设置，则 **Remote Config** 窗口会显示 \*\*JSON Editor（JSON 编辑器）\*\*对话框。您可以使用该对话框调整 JSON 值的格式并进行验证。要打开此窗口，请单击 JSON 设置所对应的 \*\*Edit（编辑）\*\*按钮：


**Frame:**
![JsonValidFormatted](/api/media?file=/remote-config/media/images/json-valid-formatted.png)

如果您输入有效但未格式化的 JSON 值，则验证指示器会显示为绿色。请使用 \*\*Format（格式）\*\*按钮来重新调整 JSON 对象的格式。


**Frame:**
![JsonUnformatted](/api/media?file=/remote-config/media/images/json-unformatted.png)

如果 json 值无效，则验证指示器会显示为红色，并且您无法提交该 JSON 对象。


**Frame:**
![JsonInvalid](/api/media?file=/remote-config/media/images/json-invalid.png)

您可以通过 \*\*Select json object（选择 json 对象）\*\*字段加载 JSON 文件（如果您的 `/Assets` 文件夹中包含该文件）。要选择文件，请单击该字段右侧的按钮。


**Frame:**
![OpenJsonFromFile](/api/media?file=/remote-config/media/images/open-json-from-file.png)

## 更新和客户端会话##updates-and-client-sessions

您无需部署新版本的应用程序，即可将更改传播到您的配置。每次玩家发起应用程序新会话时，客户端设备都会请求刷新您的 Remote Config 设置。在用户启动应用程序时，或用户在应用程序在后台保持至少 30 分钟后返回应用程序时，Remote Config 会定义一个新会话。

如果客户端没有互联网连接，无法与 Remote Config 服务通信，应用程序会使用上次收到并缓存的设置。

**注意**：从 Remote Config 服务请求设置是一个异步过程，可能无法在您的初始场景完成加载之前完成，或者在一些极端情况下可能根本不会完成。因此，请始终使用合理的默认值来初始化您的游戏变量。

## 代码集成##code-integration

在配置好您的游戏覆盖和 Settings 后，[将 Remote Config 与您的游戏代码集成](./code-integration.md)。
