This topic describes how to set up and display the Input SDK overlay in games that support Google Play Games. The tasks including adding the SDK to your game and generating an input map, which contains the game action to user input assignments. For games that support key binding changes, you must also track and synchronize the changes with the SDK.
Before you get started
Before you add the Input SDK to your game, you must add keyboard and mouse support.
Add the SDK
Get the Input SDK for Java or Kotlin by adding a dependency to your
module level build.gradle
file (this will likely be in your app
directory):
dependencies {
implementation 'com.google.android.libraries.play.games:inputmapping:1.0.0-beta'
...
}
The Input SDK for Unity is available for download in here.
Generate input mapping
Input mapping represents game actions to user input assignments to display in
the Input SDK overlay. To generate input mapping, you must build
an InputMap
and then return it with an InputMappingProvider
.
Here's an example outline of an InputMappingProvider
:
Kotlin
class MyInputMapProvider : InputMappingProvider { override fun onProvideInputMap(): InputMap { TODO("Not yet implemented") } }
Java
public class MyInputMapProvider implements InputMappingProvider { @NonNull @Override public InputMap onProvideInputMap() { // TODO: return an InputMap } }
C#
private class MyInputMappingProvider : PlayInputMappingProvider { public PlayInputMap OnProvideInputMap() { // TODO("Not yet implemented") } }
The next sections describe how to create an InputMap
to return from your
InputMappingProvider
.
Define an input action
The InputAction
class is used to map a key or key combination to a game
action.
This example maps the space key to the jump action:
Kotlin
val jumpInputAction = InputAction.create( "Jump", InputEventIds.JUMP.id, InputControls.create( listOf(KeyEvent.KEYCODE_SPACE), emptyList() ) )
Java
InputAction jumpInputAction = InputAction.create( "Jump", InputEventIds.JUMP.ordinal(), InputControls.create( Collections.singletonList(KeyEvent.KEYCODE_SPACE), Collections.emptyList() ) );
C#
var jumpInputAction = PlayInputAction.Create( "Jump", (int)InputEventIds.Jump, PlayInputControls.Create( new[] { AndroidKeyCode.KEYCODE_SPACE }, null ) );
Actions can represent mouse inputs as well. This example sets
Kotlin
val cmbMove = InputAction.create( "Move", InputEventIds.CMB_MOVE.id, InputControls.create( emptyList(), listOf(InputControls.MOUSE_RIGHT_CLICK) ) )
Java
InputAction cmbMove = InputAction.create( "Move", InputEventIds.CMB_MOVE.ordinal(), InputControls.create( Collections.emptyList(), Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK) ) );
C#
var cmbMove = PlayInputAction.Create( "Move", (int)InputEventIds.CmbMove, PlayInputControls.Create( null, new[] { PlayMouseAction.MouseRightClick } ) );
Key combinations are specified by passing multiple key codes to your
InputAction
. In this example,
Kotlin
val cmbDash = InputAction.create( "Dash", InputEventIds.CMB_DASH.id, InputControls.create( listOf(KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_SHIFT_LEFT), emptyList() ) )
Java
InputAction cmbDash = InputAction.create( "Dash", InputEventIds.CMB_DASH.ordinal(), InputControls.create( Arrays.asList(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SPACE), Collections.emptyList() ) );
C#
var cmbDash = PlayInputAction.Create( "Dash", (int)InputEventIds.CmbDash, PlayInputControls.Create( new[] { AndroidKeyCode.KEYCODE_SPACE, AndroidKeyCode.KEYCODE_SHIFT_LEFT }, null ) );
The Input SDK lets you mix mouse and key buttons together for a single command. This example indicates that shift and right-click pressed together adds a waypoint in this game:
Kotlin
val cmbWaypoint = InputAction.create( "Add Waypoint", InputEventIds.CMB_WAYPOINT.id, InputControls.create( listOf(KeyEvent.KEYCODE_SHIFT_LEFT), listOf(InputControls.MOUSE_RIGHT_CLICK) ) )
Java
InputAction cmbWaypoint = InputAction.create( "Add Waypoint", InputEventIds.CMB_WAYPOINT.ordinal(), InputControls.create( Collections.singletonList(KeyEvent.KEYCODE_SHIFT_LEFT), Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK) ) );
C#
var cmbWaypoint = PlayInputAction.Create( "Add Waypoint", (int)InputEventIds.CmbWaypoint, PlayInputControls.Create( new[] { AndroidKeyCode.KEYCODE_SHIFT_LEFT }, new[] { PlayMouseAction.MouseRightClick } ) );
This section describes the methods called in the code example:
Kotlin
InputAction.create
has these parameters:
actionLabel
is the string displayed in the UI to represent this action. Localization is not done for you, so it’s up to you to perform any localization up front.uniqueId
is an integer id to identify this action. Each action must have a consistent unique identifier, so an enumeration is used in this sample. See Tracking Key IDs for more information.inputControls
defines the input controls that the action uses. These will map to consistent glyphs in the user interface.
InputControls.create
creates the inputs associated with an action. The
parameters are:
keycodes
is a list of integers representing keyboard inputs associated with an action. These are defined in theKeyEvent
class.mouseActions
is a list of integers representing mouse inputs associated with the action. These are defined inInputControls
itself.
Java
InputAction.create
has these parameters:
actionLabel
is the string displayed in the UI to represent this action. Localization is not done for you, so it’s up to you to perform any localization up front.uniqueId
is an integer id to identify this action. Each action must have a consistent unique identifier, so an enumeration is used in this sample. See Tracking Key IDs for more information.inputControls
defines the input controls that the action uses. These will map to consistent glyphs in the user interface.
InputControls.create
creates the inputs associated with an action. The
parameters are:
keycodes
is a list of integers representing keyboard inputs associated with an action. These are defined in theKeyEvent
class.mouseActions
is a list of integers representing mouse inputs associated with this action. These are defined inInputControls
itself.
C#
InputAction
has these fields:
ActionLabel
is the string displayed in the UI to represent this action. Localization is not done for you, so it’s up to you to perform any localization up front.UniqueId
is an integer id to identify this action. Each action must have a consistent unique identifier, so an enum is used in this sample. See Tracking Key IDs.InputControls
defines the input controls that this action uses. These will map to consistent glyphs in the user interface.
InputControls
represents the inputs associated with an action. it has these
fields:
AndroidKeycodes
is a list of integers representing keyboard inputs associated with an action. These are defined in theAndroidKeycode
class.MouseActions
is a list of MouseAction values representing mouse inputs associated with this action.
Define an input group
An InputGroup
is a group of similar InputAction
objects. For example:
- You may specify different sets of inputs for navigating menus vs moving in game.
- You may specify different sets inputs depending on the mode of locomotion in your game, such as driving vs walking.
- You may specify different sets of inputs based on the current state of your game, such as navigating an overworld vs playing an individual level.
By organizing your inputs into groups, you make it easier for a player to find the correct key binding for their current situation.
Kotlin
val movementInputGroup = InputGroup.create( "Basic Movement", listOf(jumpInputAction, leftInputAction, rightInputAction, useInputAction) )
Java
InputGroup movementInputGroup = InputGroup.create( "Basic Movement", Arrays.asList(jumpInputAction, leftInputAction, rightInputAction, useInputAction) );
C#
var movementInputGroup = PlayInputGroup.Create( "Basic Movement", new[] { jumpInputAction, leftInputAction, rightInputAction, useInputAction } );
This section describes the method calls used in the code example:
Kotlin
InputGroup.create
has these parameters:
groupLabel
is a string to be displayed in the UI that can be used to logically group a set of actions. This string is not localized for you.inputActions
is a list ofInputAction
objects that you defined in the last step. All of these actions will be visually displayed under this group’s heading.
Java
InputGroup.create
has these parameters:
groupLabel
is a string to be displayed in the UI that can be used to logically group a set of actions. This string is not localized for you.inputActions
is a list ofInputAction
objects that you defined in the last step. All of these actions will be visually displayed under this group’s heading.
C#
InputGroup
has these fields:
GroupLabel
is a string to be displayed in the UI that can be used to logically group a set of actions. This string is not localized for you.InputActions
is a list ofInputAction
objects that you defined in the last step. All of these actions will be visually displayed under this group’s heading.
Build an input map
An InputMap
is a collection of all the InputGroup
objects available in a
game, and therefore all of the InputAction
objects a player can expect to
perform.
In the following example, MovementInputGroup
objects are
grouped with MouseSettings
objects. The MouseSettings
objects indicate that
mouse sensitivity can be adjusted and that the mouse is inverted on the y axis:
Kotlin
return InputMap.create( listOf(movementInputGroup, specialInputGroup), MouseSettings.create(true, true) )
Java
return InputMap.create( Arrays.asList(movementInputGroup, specialInputGroup), MouseSettings.create(true, true) );
C#
return PlayInputMap.Create( new[] { movementInputGroup, specialInputGroup, combinationInputGroup }, PlayMouseSettings.Create(true, false) );
Submit an input map
Once an InputMapProvider
has been been written for a game that returns a valid
InputMap
, it must be registered with the Input SDK. If a game's
inputs never change, this only has to be done once for the lifetime of a game
as the InputMapProvider
is not affected by Android lifecycle events.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val inputMappingClient = Input.getInputMappingClient(this) inputMappingClient.setInputMappingProvider(MyInputMapProvider()) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InputMappingClient inputMappingClient = Input.getInputMappingClient(this); inputMappingClient.setInputMappingProvider(new MyInputMapProvider()); }
C#
void Start() { _inputMappingProvider = new MyInputMappingProvider(); PlayInput.GetInputMappingClient().SetInputMappingProvider(_inputMappingProvider); }
You should unregister your input mapping provider when your game is finished, although the SDK is smart enough to avoid leaking resources if you don't.
Kotlin
override fun onDestroy() { val inputMappingClient = Input.getInputMappingClient(this) inputMappingClient.clearInputMappingProvider() super.onDestroy() }
Java
@Override protected void onDestroy() { InputMappingClient inputMappingClient = Input.getInputMappingClient(this); inputMappingClient.clearInputMappingProvider(); super.onDestroy(); }
C#
private void OnDestroy() { PlayInput.GetInputMappingClient().ClearInputMappingProvider(); }
Track key IDs
You need to track unique IDs for each InputAction
you define. The following
enumeration tracks the unique IDs for all the samples in this topic. Since the
IDs are used to track key changes, do not use a hash of the localized action
name.
Kotlin
enum class InputEventIds(val id: Int) { JUMP(0), LEFT(1), RIGHT(2), USE(3), SPECIAL_JUMP(4), SPECIAL_DUCK(5), }
Java
public enum InputEventIds { JUMP, LEFT, RIGHT, USE, SPECIAL_JUMP, SPECIAL_DUCK }
C#
public enum InputEventIds { JUMP, LEFT, RIGHT, USE, SPECIAL_JUMP, SPECIAL_DUCK }
Test
There are two ways to test whether the Input SDK has been properly
implemented. Either by opening it in the Google Play Games UI to see what
a player may see or in the adb shell
for automated testing and verification.
User interface
To test in the Google Play Games UI, press Shift+Tab to open the Game Dashboard. Fromm the dashboard, click Controls to view the list of currently bound controls.
Command line
Inputs can also be verified via adb
at the command line, which may help with
automated testing of the feature.
To get the current input map, use the following adb shell
command (replace
MY.PACKAGE.NAME
with the name of your game):
adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME
You will see output similar to this if you successfully registered your
InputMap
:
Getting input map for com.example.inputsample...
Successfully received the following inputmap:
# com.google.android.libraries.play.games.InputMap@d73526e1
input_groups {
group_label: "Basic Movement"
input_actions {
action_label: "Jump"
input_controls {
keycodes: 51
keycodes: 19
}
unique_id: 0
}
input_actions {
action_label: "Left"
input_controls {
keycodes: 29
keycodes: 21
}
unique_id: 1
}
input_actions {
action_label: "Right"
input_controls {
keycodes: 32
keycodes: 22
}
unique_id: 2
}
input_actions {
action_label: "Use"
input_controls {
keycodes: 33
keycodes: 66
mouse_actions: MOUSE_LEFT_CLICK
mouse_actions_value: 0
}
unique_id: 3
}
}
input_groups {
group_label: "Special Input"
input_actions {
action_label: "Jump"
input_controls {
keycodes: 51
keycodes: 19
keycodes: 62
mouse_actions: MOUSE_LEFT_CLICK
mouse_actions_value: 0
}
unique_id: 4
}
input_actions {
action_label: "Duck"
input_controls {
keycodes: 47
keycodes: 20
keycodes: 113
mouse_actions: MOUSE_RIGHT_CLICK
mouse_actions_value: 1
}
unique_id: 5
}
}
mouse_settings {
allow_mouse_sensitivity_adjustment: true
invert_mouse_movement: true
}
Synchronize key binding changes
Many games allow players to customize their key bindings. Therefore, you should
ensure that the data you return in InputMapProvider
is up to date for the
player's current settings. If needed, you can safely call
setInputMappingProvider
with the latest input map whenever your players
finish changing their input scheme.
Localization
The Input SDK does not use Android's localization system. As a
result, you must provide localized strings when submitting an InputMap
.
However, this also allows you to use your game engine's localization system.
What's next
After you integrate the Input SDK into your game, you can continue with any remaining Google Play Games requirements. For more information, see Get started with Google Play Games.