将适用于 Java 和 Kotlin 的输入 SDK 升级到版本 1.1

本指南介绍了如何将游戏中适用于 Java 和 Kotlin 的输入 SDK 从 1.0.0-beta 升级到 1.1.0-beta。如需了解适用于 Unity 的具体说明,请参阅适用于 Unity 的升级指南

版本说明

Google Play 游戏电脑版支持根据游戏使用输入 SDK 提供的按键绑定来重新映射键盘控制方式。

用户可以通过执行以下步骤来访问该功能:打开叠加层,选择控件,然后点击要重新映射的操作。

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

Google Play 游戏电脑版会将每位用户重新映射的控件存储在本地,所以这类控件在不同的游戏会话中将保持不变。由于是存储在本地,因此移动体验也不会受到影响;在 Google Play 游戏电脑版卸载后,这类控件将被删除。此外,控件设置不会跨多个 PC 设备保存。

您无需升级输入 SDK 即可在游戏中启用按键重新映射;但如果检测到不受支持的配置,系统可能会停用游戏的重新映射。

如果您想控制输入重新映射体验,或者系统停用了游戏的重新映射功能,请执行以下步骤进行解决:

  • 升级到输入 SDK 1.1.0-beta
  • 更新所有按键绑定,避免出现不受支持的配置
  • 更新 InputMap,将重新映射功能设为启用。

如果您想选择对游戏停用重新映射功能,同时仍显示按键绑定的只读版本,请按以下步骤操作:

  • 升级到输入 SDK 1.1.0-beta
  • 更新 InputMap,将重新映射功能设为停用。

您可以将输入 SDK 的版本升级到 1.1.0-beta,以充分利用 Google Play 游戏电脑版中的高级重新映射功能,方法是使用 InputContexts 通过 InputActionInputGroupInputMap,针对游戏的不同场景定义控件、添加回调来监听重新映射事件、定义一组用户不能重新映射的预留按键以及停用重新映射功能。

升级到新的 SDK 版本时,请考虑以下例外情况:

不受支持的配置

如果不符合以下条件,输入重新映射就会被停用:

  • 使用多个按键的 InputAction 必须由辅助键和非辅助键组成,例如:Shift 键 + A 就符合条件,但 A + BCtrl 键 + Alt 键以及 Shift 键 + A + Tab 键不符合条件。

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

升级

输入 SDK 1.1.0-beta 向后兼容输入 SDK 1.0.0-beta。采用输入 SDK 旧版实现的游戏仍然支持基本的重新映射,除非它们使用不受支持的配置。如果您的游戏使用的是较低版本的输入 SDK,不妨参阅从 0.0.4 到 1.0.0-beta 的升级指南

升级到 1.1.0-beta 可启用以下新功能:

升级依赖项

如果您使用 Gradle 来导入输入 SDK,请升级到最新版本:

// build.gradle
dependencies {
   ...
   implementation 'com.google.android.libraries.play.games:inputmapping:1.1.0-beta'
   ...
}

定义静态字段

对于版本 1.1.0-beta,最好将 InputActionInputGroupInputContextInputMap 对象定义为 InputMappingProvider 类的静态字段,因为这些字段可以从应用的其他部分访问:

Kotlin

class InputSDKProvider : InputMappingProvider {
    override fun onProvideInputMap(): InputMap { return gameInputMap }

    companion object {
        const val INPUTMAP_VERSION = "1.0.0"

        private val moveUpInputAction = InputAction.create(...)
        private val movementInputGroup = InputGroup.create(...)
        val menuContext = InputContext.create(...)
        val gameInputMap = InputMap.create(...)
    }
}

Java

public class MyInputMappingProvider implements InputMappingProvider {
    private static final String INPUTMAP_VERSION = "1.0.0";

    private static final InputAction moveUpInputAction =
        InputAction.create(...);
    private static final InputGroup movementInputGroup = InputGroup.create(...);
    public static final InputContext menuContext = InputContext.create(...);
    public static final InputMap gameInputMap = InputMap.create(...);

    @Override
    public InputMap onProvideInputMap() {
        return gameInputMap;
    }
}

更新 InputAction

输入 SDK 1.0.0-betaInputAction.create() 方法已废弃。InputAction 现在包含版本标识符,并能标记为是否可重新映射。默认情况下,使用输入 SDK 1.0.0-beta create() 方法定义的 InputAction 可重新映射,但缺少版本控制信息:

输入 SDK 1.0.0-beta 中的 InputAction

Kotlin

val jumpInputAction = InputAction.create(
    "Jump",
    InputEventIds.JUMP.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SPACE),
        emptyList()
    )
)

Java

InputAction moveUpInputAction = InputAction.create(
    "Move Up",
    InputEventIds.MOVE_UP.ordinal(),
    InputControls.create(
        Collections.singletonList(KeyEvent.KEYCODE_W),
        Collections.emptyList()
    )
);

输入 SDK 1.1.0-beta 中的 InputAction

Kotlin

companion object {
  private val moveUpInputAction = InputAction.create(
    "Move Up",
    InputActionsIds.DRIVE.ordinal.toLong(),
    InputControls.create(listOf(KeyEvent.KEYCODE_W), emptyList()),
    InputEnums.REMAP_OPTION_ENABLED) // This action is remappable
}

Java

private static final InputAction moveUpInputAction = InputAction.create(
    "Move Up",
    InputEventIds.MOVE_UP.ordinal(),
    InputControls.create(
            Collections.singletonList(KeyEvent.KEYCODE_W),
            Collections.emptyList()),
    InputEnums.REMAP_OPTION_ENABLED // this action is remappable
);

输入 SDK 1.1.0-beta 中的 InputAction(含有版本字符串)

Kotlin

private val enterMenuInputAction = InputAction.create(
    "Enter menu",
    InputControls.create(listOf(KeyEvent.KEYCODE_ENTER), emptyList()),
    InputIdentifier.create(
    INPUTMAP_VERSION, InputActionsIds.ENTER_MENU.ordinal.toLong()),
    InputEnums.REMAP_OPTION_ENABLED
)

Java

private static final InputAction moveUpInputAction = InputAction.create(
    "Move Up",
    InputControls.create(
            Collections.singletonList(KeyEvent.KEYCODE_W),
            Collections.emptyList()),
    InputIdentifier.create(
            INPUTMAP_VERSION,
            InputEventIds.MOVE_UP.ordinal()),
    InputEnums.REMAP_OPTION_ENABLED // this action is remappable
);

如需详细了解如何对按键绑定进行版本控制,请参阅跟踪按键 ID

更新 InputGroup

在输入 SDK 1.1.0-beta 中,您需要对每个 InputGroup 进行唯一标识。每个 InputAction 都属于一个 InputGroup(即相关操作的集合)。这能让用户在游戏过程中更容易发现控件,并且能够更丝滑地切换控件。在一个 InputContext 中,InputAction 必须具有与其中所有其他操作不同的唯一标识符;同样地,InputGroup 必须具有与现有的其他组不同的唯一 ID。

在本部分的示例中,游戏有两个 InputContext 对象,分别代表主菜单和游戏内容。系统会使用如下枚举对这些上下文中每个 InputGroup 所对应的 ID 进行跟踪:

Kotlin

enum class 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
}

Java

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 一样,输入 SDK 1.0.0-betaInputGroup.create() 方法已废弃。您必须使用版本标识符以及用于指明组中的 InputAction 对象是否可重新映射的布尔值来更新游戏中的 InputGroup。使用已废弃的输入 SDK 1.0.0-beta create() 方法创建的组可重新映射,其 ID 为 0 且版本 ID 为空字符串 (""):

输入 SDK 1.0.0-beta 中的 InputGroup

Kotlin

val movementInputGroup = InputGroup.create(
    "Basic Movement",
    listOf(
        moveUpInputAction,
        moveLeftInputAction,
        moveDownInputAction,
        moveRightInputAction,
        jumpInputAction,
        runInputAction)
)

Java

InputGroup movementInputGroup = InputGroup.create(
    "Basic movement",
    Arrays.asList(
        moveUpInputAction,
        moveLeftInputAction,
        moveDownInputAction,
        moveRightInputAction,
        jumpInputAction,
        runInputAction
    )
);

输入 SDK 1.1.0-beta 中的 InputGroup

Kotlin

companion object {
    private val movementInputGroup = InputGroup.create(
        "Basic movement",
        listOf(
            moveUpInputAction,
            moveLeftInputAction,
            moveDownInputAction,
            moveRightInputAction,
            jumpInputAction,
            runInputAction),
        InputGroupsIds.BASIC_MOVEMENT.ordinal.toLong(),
        // All the actions in this groups can't be remapped
        InputEnums.REMAP_OPTION_DISABLED
    )
}

Java

private static final InputGroup movementInputGroup = InputGroup.create(
    "Basic movement",
    Arrays.asList(
            moveUpInputAction,
            moveLeftInputAction,
            moveDownInputAction,
            moveRightInputAction,
            jumpInputAction,
            runInputAction
    ),
    InputGroupsIds.BASIC_MOVEMENT.ordinal(),
    // All the actions in this groups can't be remapped
    InputEnums.REMAP_OPTION_DISABLED
);

输入 SDK 1.1.0-beta 中的 InputGroup(含有版本字符串)

Kotlin

companion object {
    private val movementInputGroup  = InputGroup.create(
        "Basic movement",
        listOf(
            moveUpInputAction,
            moveLeftInputAction,
            moveDownInputAction,
            moveRightInputAction,
            jumpInputAction,
            runInputAction),
        InputIdentifier.create(
            INPUTMAP_VERSION, InputGroupsIds.BASIC_MOVEMENT.ordinal.toLong()),
        // All the actions in this groups can't be remapped
        InputEnums.REMAP_OPTION_DISABLED
    )
}

Java

private static final InputGroup movementInputGroup = InputGroup.create(
    "Basic movement",
    Arrays.asList(
            moveUpInputAction,
            moveLeftInputAction,
            moveDownInputAction,
            moveRightInputAction,
            jumpInputAction,
            runInputAction
    ),
    InputIdentifier.create(
            INPUTMAP_VERSION,
            InputGroupsIds.BASIC_MOVEMENT.ordinal()),
    // All the actions in this groups can't be remapped
    InputEnums.REMAP_OPTION_DISABLED
);

如需详细了解如何对按键绑定进行版本控制,请参阅跟踪按键 ID

更新 InputMap

输入 SDK 1.0.0-betaInputMap.create() 方法已废弃。请更新 InputMap 以指定版本标识符、彻底停用重新映射功能,或者为游戏指定您不想让用户用于重新映射的预留按键的列表。默认情况下,使用输入 SDK 1.0.0-beta create() 方法定义的每个 InputMap 都可以重新映射,通过 ID 为 0 进行标识,并且没有任何预留按键。

输入 SDK 1.0.0-beta 中的 InputMap

Kotlin

val gameInputMap = InputMap.create(
    listOf(movementInputGroup, mouseMovementInputGroup),
    MouseSettings.create(true, false)
)

Java

InputMap gameInputMap = InputMap.create(
    Arrays.asList(movementInputGroup, mouseMovementInputGroup),
    MouseSettings.create(true, false)
);

输入 SDK 1.1.0-beta 中的 InputMap

Kotlin

companion object {

  const val INPUTMAP_VERSION = "1.0.0"
  const val INPUT_MAP_ID = 0

  val gameInputMap = InputMap.create(
    listOf(movementInputGroup, mouseMovementInputGroup),
    MouseSettings.create(true, false),
    InputIdentifier.create(INPUTMAP_VERSION, INPUT_MAP_ID.toLong()),
    InputEnums.REMAP_OPTION_ENABLED,
    // Use ESCAPE as reserved key
    listof(InputControls.create(listOf(KeyEvent.KEYCODE_ESCAPE), emptyList()))
  )
}

Java


public static final String INPUT_MAP_VERSION = "1.0.0-beta";
public static final long INPUT_MAP_ID = 0;

public static final InputMap gameInputMap = InputMap.create(
        Arrays.asList(movementInputGroup, mouseMovementInputGroup),
        MouseSettings.create(true, false),
        InputIdentifier.create(INPUTMAP_VERSION, INPUT_MAP_ID),
        InputEnums.REMAP_OPTION_ENABLED,
        // Use ESC key as reserved key
        Arrays.asList(
                InputControls.create(
                        Collections.singletonList(KeyEvent.KEYCODE_ESCAPE),
                        Collections.emptyList()
                )
        )
);

后续操作

继续升级到 1.1.0-beta:使用 InputContexts 为不同的场景指定不同的控制方式,或者使用 InputRemappingListeners 获取有关重新映射事件的通知以更新游戏界面。

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