将 Unity 的输入 SDK 升级到 1.1 版

本指南介绍如何将您的游戏从 1.0 版输入 SDK 升级到 1.1 版。有关 Java 和 Kotlin 指令,请点击此处

发行说明

适用于 PC 的 Google Play 游戏支持根据您的游戏使用输入 SDK 提供的按键绑定重新映射键盘控件。

用户通过打开叠加层、选择“控件”,然后点击他们想要重新映射的操作来访问此功能。

适用于 PC 的 Google Play 游戏将每个用户重新映射的输入映射到您的游戏的默认输入。这样,您的游戏无需了解玩家的重新映射。如果您需要了解游戏内操作的新输入(例如在游戏中显示键盘控件),则可以选择注册回调以接收重新映射事件的通知。

适用于 PC 的 Google Play 游戏在本地存储用户的重新映射控件,以在游戏会话之间保持持久性。由于这些设置是本地存储的,因此它们不会影响移动体验,并且在卸载适用于 PC 的 Google Play 游戏时会被删除。设置不会在多个 PC 设备之间保持持久性。

您无需升级输入 SDK 即可在您的游戏中启用按键重新映射,但如果检测到不受支持的配置,则您的游戏的重新映射功能将被禁用。

如果您想控制输入重新映射体验或游戏的重新映射功能被禁用,请按照以下步骤操作

  • 升级到输入 SDK 1.1.1-beta
  • 更新任何按键绑定以避免不受支持的配置
  • 更新您的 InputMap 以将重新映射功能设置为启用

如果您想在仍然显示按键绑定的只读版本的情况下选择退出游戏的重新映射功能,请按照以下步骤操作

  • 升级到输入 SDK 1.1.1-beta
  • 更新您的 InputMap 以将重新映射功能设置为禁用

您可以将输入 SDK 的版本升级到 1.1.1-beta,以利用适用于 PC 的 Google Play 游戏中的高级重新映射功能,方法是使用 InputContexts 为游戏的不同场景定义控件,添加回调以侦听重新映射事件,定义一组用户无法重新映射的保留键,并按 InputActionInputGroupInputMap 禁用重新映射功能。

升级时,请考虑以下例外情况

不受支持的配置

如果未满足以下条件,则输入重新映射将被禁用

  • 利用多个键的 InputAction 必须由修饰键和非修饰键组成。例如,Shift + A有效,但A + B, Ctrl + AltShift + A + Tab无效。

  • 两个或多个 InputActionInputGroup 对象不能共享相同的唯一 ID。

引入 InputContext

使用 InputContext,游戏可以在游戏中使用相同的键执行不同的操作,而不会发生冲突。这样,如果游戏在游戏过程中使用空格键进行跳跃,在确认菜单选择时使用空格键,则玩家可以分别重新映射空格键回车键在菜单中,以及空格键向上箭头键在游戏过程中。

以下时序图显示了 setInputContext() API 在运行时的工作原理

Diagram showing the flow of the Input SDK when remapping keys.

升级

使用输入 SDK 的先前实现的游戏仍然支持基本重新映射,除非它们使用不受支持的配置。如果您的游戏使用的是旧版本的输入 SDK,请考虑阅读从 0.0.4 升级到 1.0.0-beta 的升级指南

升级到 1.1.1-beta 可启用新功能,包括

  • 触发上下文更改。
  • 接收按键映射事件的通知
  • 禁用按操作、组、上下文或映射的重新映射。

安装

Unity 插件 v1.1.1-beta 可供您使用。您需要删除游戏中安装的任何先前版本的输入 SDK,并升级到当前版本。

要将输入 SDK v1.1.1-beta 添加到您的游戏中,请参阅添加 SDK

定义静态字段

对于 1.1.1-beta 版本,最佳实践是将您的 InputActionsInputGroupsInputContextsInputMap 定义为 InputMappingProvider 类的静态字段,因为这些字段可以从应用程序的其他部分访问。

#if PLAY_GAMES_PC
using Java.Lang;
using Java.Util;
using Google.Android.Libraries.Play.Games.Inputmapping;
using Google.Android.Libraries.Play.Games.Inputmapping.Datamodel;

public class InputSDKMappingProvider : InputMappingProviderCallbackHelper
{
    public static readonly string INPUT_MAP_VERSION = "1.0.0";

    private static readonly InputAction driveInputAction =
            InputAction.Create(...);
    private static readonly InputGroup roadInputGroup = InputGroup.Create(...);
    public static readonly InputContext roadControlsContext =
            InputContext.Create(...);
    public static readonly InputMap inputMap = InputMap.Create(...);

    public override InputMap OnProvideInputMap()
    {
        return inputMap;
    }
}
#endif

更新您的 InputActions

Input SDK 1.0.0-betaInputAction.create() 方法已弃用。一个 InputAction 具有版本标识符,并且可以标记为可重新映射或不可重新映射。使用 Input SDK 1.0.0-betacreate() 方法定义的 InputAction 默认情况下是可重新映射的,并且缺少版本信息。

Input SDK 1.0.0-beta 中的 InputAction

var driveAction = PlayInputAction.Create(
    "Drive",
    (long)InputEventIds.DRIVE,
    PlayInputControls.Create(
        new[] { AndroidKeyCode.KEYCODE_SPACE },
        new List<PlayMouseAction>()
    )
);

Input SDK 1.1.1-beta 中的 InputAction

private static readonly InputAction driveInputAction = InputAction.Create(
    "Drive",
    (long)InputEventIds.DRIVE,
    InputControls.Create(
        new[] { new Integer(AndroidKeyCode.KEYCODE_SPACE) }.ToJavaList(),
        new ArrayList<Integer>()),
    InputEnums.REMAP_OPTION_ENABLED
);

Input SDK 1.1.1-beta 中的 InputAction(带有版本字符串)

private static readonly InputAction driveInputAction = InputAction.Create(
    "Drive",
    InputControls.Create(
        new[] { new Integer(AndroidKeyCode.KEYCODE_SPACE) }.ToJavaList(),
        new ArrayList<Integer>()),
    InputIdentifier.Create(
        INPUT_MAP_VERSION, (long)InputEventIds.DRIVE),
    InputEnums.REMAP_OPTION_ENABLED
);

有关键绑定版本控制的更多信息,请参阅 跟踪键 ID

更新您的 InputGroups

在 Input SDK 1.1.1-beta 中,您需要唯一标识每个 InputGroup。每个 InputAction 都属于一个 InputGroup——一个相关操作的集合。这可以提高游戏过程中控件的导航和可发现性。就像 InputAction 在单个 InputContext 中的所有操作中必须具有唯一的标识符一样,InputGroup 在现有组中也必须具有唯一的 ID。

在本节中的示例中,一个游戏有两个 InputContext 对象,分别表示主菜单和游戏玩法。使用以下枚举在这些上下文中跟踪每个 InputGroup 的相应 ID。

public enum InputGroupsIds
{
    // Main menu scene
    BASIC_NAVIGATION, // WASD, Enter, Backspace
    MENU_ACTIONS, // C: chat, Space: quick game, S: store
    // Gameplay scene
    BASIC_MOVEMENT, // WASD, space: jump, Shift: run
    MOUSE_ACTIONS, // Left click: shoot, Right click: aim
    EMOJIS, // Emojis with keys 1,2,3,4 and 5
    GAME_ACTIONS, // M: map, P: pause, R: reload
}

InputAction 类似,Input SDK 1.0.0-betaInputGroup.create() 方法已弃用。您必须使用版本标识符和一个布尔值更新游戏中的 InputGroup,该布尔值指示组中的 InputAction 对象是否可重新映射。使用已弃用的 Input SDK 1.0.0-beta create() 方法创建的组是可重新映射的,ID 为 0,版本 ID 为空字符串 ("")。

Input SDK 1.0.0-beta 中的 InputGroup

var gameInputGroup = PlayInputGroup.Create(
    "Road controls",
    new List<PlayInputAction>
    {
        driveAction,
        turboAction,
        openGarageAction,
        openPgsAction,
        openStoreAction
    }
);

Input SDK 1.1.1-beta 中的 InputGroup

private static readonly InputGroup roadInputGroup = InputGroup.Create(
    "Road controls",
    new[]
    {
        driveInputAction,
        turboInputAction,
        openGarageInputAction,
        openPgsInputAction,
        openStoreInputAction,
    }.ToJavaList(),
    (long)InputGroupsIds.ROAD_CONTROLS,
    // All input actions of this group will be remappable unless specified
    // the contrary by the individual input actions.
    InputEnums.REMAP_OPTION_ENABLED
);

Input SDK 1.1.1-beta 中的 InputGroup(带有版本字符串)

private static readonly InputGroup roadInputGroup = InputGroup.Create(
    "Road controls",
    new[]
    {
        driveInputAction,
        turboInputAction,
        openGarageInputAction,
        openPgsInputAction,
        openStoreInputAction,
    }.ToJavaList(),
    InputIdentifier.Create(
        INPUT_MAP_VERSION, (long)InputGroupsIds.ROAD_CONTROLS),
    // All input actions of this group will be remappable unless specified
    // the contrary by the individual input actions.
    InputEnums.REMAP_OPTION_ENABLED
);

有关键绑定版本控制的更多信息,请参阅 跟踪键 ID

更新您的 InputMap

Input SDK 1.0.0-betaInputMap.create() 方法已弃用。更新您的 InputMap 以分配版本标识符,完全退出重新映射功能或为您的游戏分配一个您不希望用户用于重新映射的保留键列表。使用 Input SDK 1.0.0-beta create() 方法定义的每个 InputMap 默认情况下是可重新映射的,ID 为 0,并且没有任何保留键。

Input SDK 1.0.0-beta 中的 InputMap

var gameInputMap = PlayInputMap.Create(
    new List<PlayInputGroup>
    {
        gameInputGroup,
        menuInputGroup
    },
    PlayMouseSettings.Create(false, false)
);

Input SDK 1.1.1-beta 中的 InputMap


public static readonly string INPUT_MAP_VERSION = "1.0.0";
public static readonly long INPUT_MAP_ID = 0;

public static readonly InputMap inputMap = InputMap.Create(
    new[] { roadInputGroup, menuInputGroup }.ToJavaList(),
    MouseSettings.Create(false, false),
    InputIdentifier.Create(INPUT_MAP_VERSION, INPUT_MAP_ID),
    // Use ESC as reserved key
    InputEnums.REMAP_OPTION_ENABLED,
    new[]
    {
        InputControls.Create(new[]
        {
            new Integer(AndroidKeyCode.KEYCODE_ESCAPE)
        }.ToJavaList(),
        new ArrayList<Integer>())
    }.ToJavaList()
);

接下来做什么

通过 使用 InputContexts 为不同的场景分配不同的控件 或通过 使用 InputRemappingListeners 获取重新映射事件的通知 更新游戏 UI,继续升级到 1.1.1-beta。

在更新键绑定时,请查看 设计键绑定的最佳实践,并考虑重新映射功能的 限制局限性