模板
模板可用于远程配置以定义 JSON 密钥的形状。这使您可以验证游戏配置中的数据,并确保所做的任何更新都符合游戏客户端期望的形状。
要定义模板,您需要创建一个JSON 架构以定义数据的约束,并将其附加到一个或多个密钥。在远程配置、游戏覆盖或远程配置 API 中对这些密钥进行的任何未来更新都必须满足模板中定义的架构约束。
模板为游戏中的实时更新提供了另一层安全保障。例如,开发人员可以在初始实现中使用约束配置模板,然后将其交给他们的实时运营团队以安全地进行更新。
入门
要创建模板并将其添加到现有远程配置密钥,请完成以下步骤
- 在 Unity 云仪表板中,打开**远程配置**,并在侧边栏中选择**模板**。
- 选择**新建模板**。
- 在 JSON 编辑器字段中输入模板的架构(使用JSON 架构修订版 7格式)。
$id
字段是必需的,并且必须是唯一的 URI。title
字段也是必需的,应将其用作模板的人类可读参考。description
字段是可选的,可用于为您的同事提供更长的描述。- 选择**添加**。
- 导航到**配置**页面,创建新的 JSON 密钥或编辑现有密钥。
- 在**类型**字段中选择**JSON**。
- 从**模板**下拉列表中选择此密钥的模板。
- 选择**下一步**。
- 更新密钥的**值**以确保它与模板匹配。
- 选择**提交**以保存密钥。
小贴士
您可以使用在线架构生成器(例如JSON 到 JSON 架构)来获取现有密钥的 JSON 并创建一个新的架构作为起点。
将文件添加到模板
使用有效的云内容交付订阅,您可以在模板中包含文件并通过远程配置上传它们。
要将文件添加到您的模板,请在定义中添加一个新属性,类型为object
,子类型为file
...
"properties": {
"myImage": {
"type": "object",
"subtype": "file"
}
}
...
添加文件字段并将模板应用于远程配置密钥后,您可以在本地设备上选择一个文件上传到 CCD。CDN 链接、文件名和大小将添加到值中。您可以在游戏客户端中使用 CDN 链接在运行时获取资产。提供给游戏客户端的文件计入您的总 CCD 使用量和计费。
> Note: Before the first file upload, you'll be prompted to set up the CCD bucket when editing the selected value in Remote Config.
为了增加安全性,您可以为您的对象添加必需字段
...
"properties": {
"myImage": {
"type": "object",
"subtype": "file",
"properties": {
"name": {
"type": "string"
},
"size": {
"type": "number"
},
"url": {
"type": "string"
}
},
"required": [
"name",
"size",
"url"
]
}
}
...
用例
您可以使用模板通过JSON 架构修订版 7提供的约束来实现各种用例。下表提供了一些示例用例以及相关参考的链接。
用例 | 相关参考 |
---|---|
确保任务始终具有名称和 ID,并且 ID 始终是数字。 | 必需属性和类型。 |
为季节性事件的名称设置最大长度,以确保它不会在游戏 UI 中换行。 | 字符串格式。 |
确保游戏内消息的日期符合ISO8601 标准,并且支持联系电话是美国电话号码。 | 内置字符串格式和正则表达式。 |
为关卡难度设置最大值,并确保它始终是 5 的倍数。 | 数字范围和倍数。 |
确保季节性事件的奖励始终是特定字符串。 | 枚举值. |
确保当您定义任务对象时,也始终定义奖励。 | 条件验证. |
将图像添加到游戏内促销弹出窗口 | 将文件添加到模板 |
示例
您可以使用模板为对游戏的任何更改定义形状。以下示例提供了一些建议,以帮助您入门,您可以根据需要对其进行编辑。
任务数组的必需属性和类型
以下是一个单级密钥的架构,该密钥配置多个任务,每个任务都必须具有名称字符串和数字 ID。
{
"$id": "#missions",
"title": "Missions",
"description": "The missions in the game.",
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"ID": {
"type": "number"
}
},
"required": ["name", "ID"]
}
}
游戏内消息的字符串格式
为字符串设置最大长度,设置日期格式并使用正则表达式检查字符串的格式。
{
"$id": "#in-game-inbox",
"title": "In-Game Inbox",
"description": "The in-game inbox.",
"type": "object",
"properties": {
"messageID": {
"type": "number"
},
"messageContent": {
"type": "string",
"maxLength": 500
},
"sendDate": {
"type": "string",
"format": "date-time"
},
"supportContactNumber": {
"type": "string",
"pattern": "^\\+1\\s\\([0-9]{3}\\)\\s[0-9]{3}-[0-9]{4}$"
}
},
"required": ["messageID", "messageContent", "sendDate", "supportContactNumber"]
}
关卡难度的数字格式
为关卡难度字段设置最小值和最大值,并确保它始终是 5 的倍数。
{
"$id": "#levels",
"title": "Levels",
"description": "The levels in the game.",
"type": "array",
"items": {
"type": "object",
"properties": {
"levelID": {
"type": "number"
},
"levelName": {
"type": "string"
},
"difficulty": {
"type": "number",
"minimum": 0,
"maximum": 100,
"multipleOf": 5
}
},
"required": ["levelID", "levelName", "difficulty"]
}
}
使用枚举列表为季节性事件奖励
{
"$id": "#seasonal-event",
"title": "Seasonal Event",
"description": "The seasonal event.",
"type": "object",
"properties": {
"eventID": {
"type": "number"
},
"eventName": {
"type": "string"
},
"description": {
"type": "string"
},
"reward": {
"type": "string",
"enum": ["Gold Coins", "Special Item", "Bonus Points", "Exclusive Access"]
}
},
"required": ["eventID", "eventName", "description", "reward"]
}
在定义任务时有条件地要求任务详细信息字段
此架构确保只要定义了任务类型,任务详细信息对象就是必需的,奖励也是如此。
{
"$id": "#missions",
"title": "Missions",
"description": "The missions in the game.",
"type": "object",
"properties": {
"missionType": {
"type": "string",
"enum": ["Combat", "Exploration", "Puzzle"]
},
"missionDetails": {
"type": "object"
},
"reward": {
"type": "object",
"properties": {
"rewardType": {
"type": "string",
"enum": ["Item", "Currency", "Experience"]
},
"rewardDetails": {
"type": "object"
}
}
}
},
"dependentRequired": {
"missionType": ["missionDetails"],
"rewardType": ["rewardDetails"]
}
}
将图像添加到游戏内促销弹出窗口
此架构包含图像文件和游戏内促销弹出窗口的相关信息。
{
"$id": "#seasonal-promo",
"title": "Seasonal Promo",
"description": "The seasonal promo.",
"type": "object",
"properties": {
"promoID": {
"type": "number"
},
"promoName": {
"type": "string"
},
"description": {
"type": "string"
},
"shopDiscount": {
"type": "number"
},
"promoItemID": {
"type": "number"
},
"popUpImage": {
"type": "object",
"subtype": "file"
}
},
"required": ["promoID", "promoName", "shopDiscount", "promoItemID", "popUpImage"]
}