将适用于 Unity 的 Input SDK 升级到版本 1.1

本指南介绍了如何将您的游戏从 1.0 Input SDK 升级到 1.1 Input SDK for Unity。点击此处查看 Java 和 Kotlin 说明。

发布说明

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

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

PC 版 Google Play 游戏会将每个用户重新映射的输入映射到您游戏的默认输入。这样,您的游戏就不必知道玩家的重新映射。如果您需要知道游戏中某个操作的新输入(例如在游戏中显示键盘控件),您可以选择注册回调,以便在重新映射事件发生时收到通知。

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

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

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

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

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

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

您可以将 Input 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.

升级

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

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

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

安装

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

要将 Input 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-beta create() 方法定义的 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。

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