根据游戏状态更改触摸控件布局

游戏能够更改正在向玩家展示的触控布局,或修改当前所示布局使用的状态。 这两种方法可以一起使用,为玩家创造最自然的体验。

更改布局

更改布局应在以下情况下使用:

  • 在不同的控制方案之间切换(例如,驾驶车辆和第一人称射击)
  • 暂时隐藏触控布局(若要获得完整的触控体验,请启用电影体验等)

更改状态

更改触控适配捆绑包上下文部分中包含的游戏状态应在以下情况下使用:

  • 根据玩家的当前游戏状态修改控件的图像/图标。 一些示例如下:
    • 根据玩家选择的武器更改“射击”按钮上的图像。
    • 根据玩家物品栏中当前的道具更改能力图像。
  • 根据玩家的当前游戏状态修改控件的可视状态(可视度已启用)。 一些示例如下:
    • 当玩家没有额外的弹药时,禁用“重新装载”按钮。
    • 当玩家接近他们可以与之互动的道具时,将“互动”按钮设为可见(在离开时设为不可见)。

在运行时更改布局

显示指定的布局 游戏应使用 XGameStreamingShowTouchControlLayout API 显示新布局。

隐藏当前布局 游戏应使用 XGameStreamingHideTouchControls API 隐藏当前显示的布局。

以下示例说明游戏如何根据当前游戏状态设置布局:

void OnGameStateChanged(GameState newState)
{
    // Toggle to the set of touch overlay controls which best match the new state of the game
    switch (newState)
    {
    case GameState::FirstPersonAction:
        XGameStreamingShowTouchControlLayout("FirstPersonAction");
        break;
    case GameState::Driving:
        XGameStreamingShowTouchControlLayout("Driving");
        break;
    case GameState::CutScene:
        // Don't show any touch overlay controls while the cut scene is rendering
        XGameStreamingHideTouchControls();
        break;
    }
}

在运行时更改状态

游戏启动时的初始状态由触控适配捆绑包中包含的 默认状态 定义。 在触摸控件布局中,控件应引用可能在运行时更改的属性的状态。

游戏可以利用 XGameStreamingUpdateTouchControlsState API 在运行时更新状态。

例如,以下项可用于禁用已启动的“重新装载”控件,但在这些控件应具有该功能时将其启用。

//Example context file
{
  "$schema": "https://raw.githubusercontent.com/microsoft/xbox-game-streaming-tools/main/touch-adaptation-kit/schemas/context/v3.0/context.json",

  "state": {
    "enableReload": false
  }
}

//Example control in the layout:
{
    "type": "button",
    "action": "leftBumper",
    "enabled": {
        "$ref": "../../context.json#/state/enableReload"
    }
    ...
}

游戏会进行 API 调用以更新状态:


// In this example, after the player has switched their active weapon - the game updates the
// enabled state of reload based on whether the player has extra magazines.
//
// Assumes passing in game structure that includes the active weapon with appropriate state.
//

void GameStreamingClientManager::UpdateStateAfterItemsChange(const playerWeapon& playerWeapon)
{
    // create an update for whether the reload button should be enabled
    XGameStreamingTouchControlsStateOperation reloadEnabled;
    reloadEnabled.operationKind = XGameStreamingTouchControlsStateOperationKind::Replace;
    reloadEnabled.path = "/enableReload";
    reloadEnabled.valueKind = XGameStreamingTouchControlsStateValueKind::Bool;
    reloadEnabled.booleanValue = playerWeapon.activeWeapon.reloadClips > 0;

    // combine all the updates into the update state call and make the call
    XGameStreamingTouchControlsStateOperation[1] updateOperations = {reloadEnabled};

    XGameStreamingUpdateTouchControlsState(updateOperations, _countof(updateOperations));
}