命令批处理

命令批处理是一种概念,其中每个游戏动作都是一个命令,可以将这些命令收集到一个队列中,然后批量发送到服务器进行处理。命令批处理可以优化游戏的带宽,使其尽可能节能,并防止由于频繁的服务器调用或速率限制而导致性能不佳。这提供了更流畅的游戏体验,减少了停机时间。

在此示例中,玩家的回合数是固定的。每个模拟动作都会生成一个缓存的命令,然后在游戏结束时由服务器作为批处理的一部分执行,从而减少对服务器的调用次数。

例如,假设有一款游戏在每次动作后都会调用云存档来分配玩家经验值,并调用经济服务来分配金币。玩家完成以下三个动作

  • 第一个动作获得 100 点经验值和 10 个金币。
  • 第二个动作获得 50 点经验值和 5 个金币。
  • 第三个动作获得 200 点经验值和 30 个金币。

这三个动作至少需要调用六次 Unity 服务(在本例中为云存档和经济服务)。但是,如果将这三个动作都存储为批处理命令并一次性处理,则游戏只会进行两次 Unity 服务调用:一次调用云存档以增加 350 点经验值,一次调用经济服务以增加 45 个金币。

先决条件

要使用此示例用例,您必须下载并安装 Unity 项目中的 UGS 用例项目。

概述

要查看此用例的实际效果,请打开示例菜单并导航到**命令批处理**。要直接打开此场景并与用例交互

  1. 在 Unity 编辑器**项目**窗口中,选择**资源** > **用例示例** > **命令批处理**,然后双击 `CommandBatchingSample.unity` 以打开示例场景。
  2. 按**播放**进入播放模式。

初始化

`CommandBatchingSceneManager.cs` 脚本在其 `Start` 函数中执行以下初始化任务

  1. 初始化 Unity Gaming Services。
  2. 使用身份验证服务以匿名方式让玩家登录。如果您之前已初始化任何其他示例场景,则身份验证将使用您缓存的玩家 ID,而不是创建新的 ID。
  3. 从经济服务中检索并更新玩家的货币余额。
  4. 初始化游戏界面和按钮。

功能

玩家回合

在此示例中,一个“游戏”包含固定数量的回合,每个回合都可以通过单击四个按钮之一来完成。每个按钮代表一个模拟动作,并具有相应的奖励。当您单击其中一个动作按钮时,会发生以下情况

  1. 按钮的 `OnClick` 方法调用 `CommandBatchingSceneManager.cs` 脚本,该脚本会消耗一个回合。

  2. 然后,该脚本会生成与您单击的动作关联的命令,并将其发送到批处理队列以供将来服务器处理。每个命令都使用远程配置值来映射相应动作的奖励。

  3. 它还会调用该动作关联的 `CommandSystem` 脚本,以将奖励分发给客户端。

    **注意**:本地奖励分发允许玩家立即看到回合结果,但这不是服务器授权的。服务器在验证并处理游戏结束时的所有命令后,会覆盖所有本地分发。

  4. 最后,调用脚本会检查玩家是否还有剩余回合,如果有,则会触发游戏结束条件。

游戏结束

当玩家剩余回合数为零时,游戏结束。会发生以下情况

  1. 客户端将最终的游戏结束命令添加到批处理队列。
  2. 客户端将整个命令队列作为单个 JSON 发送到云代码。
  3. `CommandBatch_ProcessBatch.js` 云代码脚本将 JSON blob 解包回命令列表,然后验证批处理是否包含预期数量的有效顺序命令(例如,在出现**打开宝箱**命令之前,玩家不能触发**达成奖励目标**命令)。
  4. 如果批处理有效,则云代码脚本会检索要从远程配置值分发的奖励,然后直接通过经济服务(货币)和云存档服务(经验值和 `GoalsAchieved`)发出奖励。如果批处理无效,则脚本会返回错误,并且不会在服务器上分发奖励。

在远程配置中映射奖励允许您在一个位置远程调整奖励,同时影响客户端和服务器端的分发。批处理中所有命令的奖励都按类型分组,因此如果多个命令增加了经验值,则总经验值收益会累加,并通过一次对云存档的服务器调用进行更新。

无论云代码脚本返回成功还是失败,客户端代码都会调用 Unity 服务以检索其最新数据。如果服务器成功处理了批处理,则这对玩家的货币、`GoalsAchieved` 或经验值 HUD 应该没有可见的变化,因为从玩家的角度来看,奖励是在游戏过程中立即分发的。但是,如果云代码脚本未能处理无效的批处理,则客户端会将玩家的状态更新回玩游戏之前的状态,从而覆盖本地状态。

**注意**:这会创建一个混合授权游戏。在某些时候,游戏依赖于本地(客户端)权限来了解玩家的统计数据和货币余额。但是,服务器最终对玩家的状态拥有最终权限。虽然这种混合权限设置并不适用于所有游戏类型,但它对其他游戏类型非常有用,例如回合制游戏、单人游戏、无尽跑酷游戏和益智游戏。在选择提供离线支持或在连接不良情况下保持容错的游戏中,命令批处理也可以作为开发解决方案的一个良好起点。

设置

要求

要复现此用例,您需要在项目中包含以下Unity 包

角色
身份验证自动将玩家作为匿名用户登录,以跟踪他们在服务器端的数据。
云代码在游戏结束时处理排队的命令。
云存档存储命令与其对应奖励之间的映射,客户端和云代码引用此映射来分发奖励。
部署提供用于部署云服务资源的统一接口。
经济在运行时检索玩家的起始货币余额和更新后的货币余额。
远程配置维护玩家统计数据的键值存储,例如经验值和已达成目标。

要在您的游戏中使用这些服务,请在Unity Cloud Dashboard中为您的组织和项目激活每项服务。

Unity Cloud 服务配置

要在您自己的 Unity 项目中复现此示例场景的设置,请配置以下项目

  • 云代码脚本
  • 经济项目
  • 远程配置值

要配置这些项目,您可以使用部署包,也可以使用 Unity Cloud Dashboard 手动输入。建议的最佳实践是使用部署包,因为它可以大大加快此过程。

使用部署包

要使用部署包部署配置

  1. 打开部署窗口
  2. 选中**通用**和**命令批处理**。
  3. 单击**部署选择**。

这将部署所有必需的项目。

使用 Unity Cloud Dashboard

您可以使用Unity Cloud Dashboard按项目和环境手动配置您的服务。请参阅以下部分以配置此示例。

云代码

在 Unity Cloud Dashboard 中发布以下脚本

脚本参数描述项目中的位置
GrantEventRewardbatch

命令键数组。例如:

{
  "commands": [
    "COMMANDBATCH_DEFEAT_RED_ENEMY", 
    "COMMANDBATCH_OPEN_CHEST", 
    "COMMANDBATCH_ACHIEVE_BONUS_GOAL", 
    "COMMANDBATCH_DEFEAT_BLUE_ENEMY", 
    "COMMANDBATCH_OPEN_CHEST", 
    "COMMANDBATCH_ACHIEVE_BONUS_GOAL", 
    "COMMANDBATCH_GAME_OVER"
  ]
}
在游戏结束时处理排队的命令。Assets/Use Case Samples/Command Batching/Cloud Code/CommandBatch_ProcessBatch.js

注意Cloud Code 文件夹中包含的 Cloud Code 脚本是本地副本,因为您无法查看示例项目的控制面板。对这些脚本的更改不会影响此示例的行为,因为它们不会自动上传到 Cloud Code 服务。

经济

在 Unity Cloud Dashboard 中配置以下资源

资源类型资源名称ID描述
货币金币COIN某些操作的奖励。
货币宝石GEM某些操作的奖励。

远程配置

在 Unity Cloud Dashboard 中设置以下配置值

类型描述
COMMANDBATCH_ACHIEVE_BONUS_GOALJSON将**达成奖励目标**命令映射到其对应的奖励。
{
  "rewards":[{
    "service": "cloudSave",
    "id": "COMMANDBATCH_XP",
    "amount": 150
  }, 
  {
    "service": "cloudSave",
    "id": “COMMANDBATCH_GOALSACHIEVED",
    "amount": 1
  }]
}
COMMANDBATCH_DEFEAT_BLUE_ENEMYJSON将**击败蓝色敌人**按钮操作映射到其对应的奖励。
{
  "rewards":[{
    "service": "cloudSave",
    "id": "COMMANDBATCH_XP",
    "amount": 50
  }, 
  {
    "service": "currency",
    "id": “GEM",
    "amount": 5
  }]
}
COMMANDBATCH_DEFEAT_RED_ENEMYJSON将**击败红色敌人**按钮操作映射到其对应的奖励。
{
  "rewards":[{
    "service": "cloudSave",
    "id": "COMMANDBATCH_XP",
    "amount": 50
  }, 
  {
    "service": "currency",
    "id": “COIN",
    "amount": 5
  }]
}
COMMANDBATCH_OPEN_CHESTJSON将**打开宝箱**按钮操作映射到其对应的奖励。
{
  "rewards":[{
    "service": "cloudSave",
    "id": "COMMANDBATCH_XP",
    "amount": 100
  },
  {
    "service": "currency",
    "id": “COIN",
    "amount": 25
  }, 
  {
    "service": "currency",
    "id": “GEM",
    "amount": 25
  }]
}
COMMANDBATCH_GAME_OVERJSON将游戏结束命令(没有剩余回合)映射到其对应的奖励。
{
  "rewards":[{
    "service": "cloudSave",
    "id": "COMMANDBATCH_XP",
    "amount": 100
  }]
}