In diesem Dokument wird beschrieben, wie das Input SDK in Spielen eingerichtet und angezeigt wird, die Google Play Spiele auf dem PC unterstützen. Zu den Aufgaben gehört das Hinzufügen des SDK zu Ihrem Spiel und das Generieren einer Eingabezuordnung, die die Zuweisungen von Spielaktionen an Nutzereingaben enthält.
Vorbereitung
Bevor Sie Ihrem Spiel das Input SDK hinzufügen, müssen Sie die Tastatur- und Mauseingabe über das Eingabesystem der Spiel-Engine unterstützen.
Das Input SDK stellt Google Play Spiele auf dem PC Informationen darüber zur Verfügung, welche Steuerelemente Ihr Spiel verwendet, damit sie dem Nutzer angezeigt werden können. Optional kann die Tastatur auch für Nutzer neu zugeordnet werden.
Jedes Steuerelement ist ein InputAction
(z.B. „J“ für „Jump“) und Sie organisieren Ihr InputActions
in InputGroups
. Ein InputGroup
kann einen anderen Modus in deinem Spiel darstellen, z. B. „Fahren“, „Zu Fuß“ oder „Hauptmenü“. Du kannst auch InputContexts
verwenden, um anzugeben, welche Gruppen zu verschiedenen Zeitpunkten im Spiel aktiv sind.
Sie können festlegen, dass die Neuzuordnung der Tastatur automatisch für Sie durchgeführt wird. Wenn Sie jedoch eine eigene Schnittstelle für die Neuzuordnung von Steuerelementen bereitstellen möchten, können Sie die Neuzuordnung des Eingabe-SDKs deaktivieren.
Das folgende Sequenzdiagramm beschreibt, wie die API des Input SDK funktioniert:
Wenn das Input SDK in Ihrem Spiel implementiert ist, werden Ihre Steuerelemente im Overlay von Google Play Spiele auf dem PC angezeigt.
Overlay für Google Play Spiele auf dem PC
Das Overlay von Google Play Spiele auf dem PC („Overlay“) zeigt die von Ihrem Spiel definierten Steuerelemente an. Das Overlay kann jederzeit durch Drücken von Shift + Tabulatortaste aufgerufen werden.
Best Practices für das Entwerfen von Schlüsselbindungen
Berücksichtigen Sie beim Entwerfen Ihrer Schlüsselbindungen die folgenden Best Practices:
- Gruppiere dein
InputActions
in logisch zusammengehörigeInputGroups
, um die Navigation und die Sichtbarkeit der Steuerelemente während des Spiels zu verbessern. - Weisen Sie jedes
InputGroup
maximal einemInputContext
zu. Ein feines Detail desInputMap
ermöglicht eine einfachere Navigation der Steuerelemente im Overlay. - Erstelle eine
InputContext
für jeden Szenentyp deines Spiels. In der Regel können Sie für alle Ihre „menüähnlichen“ Szenen eine einzelneInputContext
verwenden. Verwende unterschiedlicheInputContexts
für alle Minispiele in deinem Spiel oder für alternative Steuerelemente für eine einzelne Szene. - Wenn zwei Aktionen denselben Schlüssel unter demselben
InputContext
verwenden sollen, verwenden Sie den Labelstring, z. B. „Interagieren / feuer“. - Wenn zwei Schlüssel an dasselbe
InputAction
gebunden werden sollen, verwenden Sie zwei verschiedeneInputActions
, die die gleiche Aktion in Ihrem Spiel ausführen. Sie können für beideInputActions
denselben Labelstring verwenden, die ID muss jedoch unterschiedlich sein. - Wenn eine Modifikatortaste auf eine Gruppe von Tasten angewendet wird, sollten Sie statt mehrerer
InputActions
mit der Modifikatortaste ein einzelnesInputAction
mit der Modifikatortaste verwenden. Verwenden Sie beispielsweise Umschalttaste und W, A, S, D statt Umschalttaste + W, Umschalttaste + A, Umschalttaste + S, Umschalttaste + D. - Die Neuzuordnung von Eingaben wird automatisch deaktiviert, wenn der Nutzer in Textfelder schreibt. Beachten Sie die Best Practices für die Implementierung von Android-Textfeldern. So sorgen Sie dafür, dass Android Textfelder in Ihrem Spiel erkennen kann und nicht durch neu zugeordnete Schlüssel beeinträchtigt wird. Wenn in Ihrem Spiel nicht-konventionelle Textfelder verwendet werden müssen, können Sie
setInputContext()
mit einemInputContext
verwenden, das eine leere Liste mitInputGroups
enthält, um die Neuzuordnung manuell zu deaktivieren. - Wenn Ihr Spiel Neuzuordnungen unterstützt, sollten Sie Ihre Tastenkombinationen aktualisieren. Dies ist ein sensibler Vorgang, der mit den vom Nutzer gespeicherten Versionen in Konflikt stehen kann. Ändern Sie die IDs vorhandener Steuerelemente nach Möglichkeit nicht.
Die Funktion für die Neuzuordnung von Karteninhalten
Google Play Spiele auf dem PC unterstützt die Neuzuordnung der Tastatursteuerung basierend auf den Tastenkombination, die dein Spiel über das Input SDK bereitstellt. Dies ist optional und kann vollständig deaktiviert werden. Sie können beispielsweise eine eigene Oberfläche für die Neuzuordnung der Tastatur bereitstellen. Wenn Sie die Neuzuordnung für Ihr Spiel deaktivieren möchten, müssen Sie nur die Option für die Neuzuordnung festlegen, die für InputMap
deaktiviert ist. Weitere Informationen finden Sie unter InputMap erstellen.
Um auf diese Funktion zuzugreifen, müssen Nutzer das Overlay öffnen und dann auf die Aktion klicken, die sie neu zuordnen möchten. Nach jedem Neuzuordnungsereignis wird in Google Play Spiele auf dem PC jedem Nutzer eine neue Steuerung der Standardsteuerelemente zugewiesen, die Ihr Spiel erwarten soll. Ihr Spiel muss also die Neuzuordnungen des Spielers nicht erkennen. Du kannst optional die Assets aktualisieren, die zum Anzeigen der Tastatursteuerung in deinem Spiel verwendet werden. Füge dazu einen Callback für die Neuzuordnung von Ereignissen hinzu.
Google Play Spiele auf dem PC speichert neu zugeordnete Steuerelemente lokal für jeden Nutzer, sodass die Steuerung über Spielesitzungen hinweg aufrechterhalten werden kann. Diese Informationen werden nur für die PC-Plattform auf dem Laufwerk gespeichert und haben keine Auswirkungen auf die mobile Nutzung. Kontrolldaten werden gelöscht, wenn der Nutzer Google Play Spiele auf dem PC deinstalliert oder neu installiert. Diese Daten werden nicht über mehrere PC-Geräte hinweg gespeichert.
Damit die Funktion zur Neuzuordnung in Ihrem Spiel unterstützt wird, müssen Sie die folgenden Einschränkungen beachten:
Einschränkungen bei der Neuzuordnung
Die Funktionen zur Neuzuordnung von Elementen können in Ihrem Spiel deaktiviert werden, wenn die Tastenkombination eine der folgenden Fälle enthält:
InputActions
mit mehreren Schlüsseln, die nicht aus einer Modifikatortaste und einem Nicht-Modifikatorschlüssel bestehen. Beispielsweise ist Umschalttaste + A gültig, A + B, Strg + Alt oder Umschalttaste + A + Tabulatortaste jedoch nicht.InputMap
enthältInputActions
,InputGroups
oderInputContexts
mit wiederholten eindeutigen IDs.
Einschränkungen der Neuzuordnung
Berücksichtigen Sie beim Entwerfen Ihrer Schlüsselbindungen für die Neuzuordnung die folgenden Einschränkungen:
- Eine Neuzuordnung zu Tastenkombinationen wird nicht unterstützt. Beispielsweise können Nutzer Umschalttaste + A nicht zu Strg + B oder A zu Umschalttaste + A zuordnen.
- Die Neuzuordnung wird für
InputActions
mit Maustasten nicht unterstützt. Umschalttaste + Rechtsklick kann beispielsweise nicht neu zugeordnet werden.
Neuzuordnung von Tasten im Emulator für Google Play Spiele auf dem PC testen
Sie können die Funktion für die Neuzuordnung im Emulator für Google Play Spiele auf dem PC jederzeit mit dem folgenden ADB-Befehl aktivieren:
adb shell dumpsys input_mapping_service --set RemappingFlagValue true
Das Overlay ändert sich wie in der folgenden Abbildung:
SDK hinzufügen
Installieren Sie das Input SDK entsprechend Ihrer Entwicklungsplattform.
Java und Kotlin
Rufen Sie das Input SDK für Java oder Kotlin ab, indem Sie der Datei build.gradle
auf Modulebene eine Abhängigkeit hinzufügen:
dependencies {
implementation 'com.google.android.libraries.play.games:inputmapping:1.1.0-beta'
...
}
Unity
Das Input SDK ist ein Standard-Unity-Paket mit mehreren Abhängigkeiten.
Das Paket muss mit allen Abhängigkeiten installiert werden. Es gibt mehrere Möglichkeiten, die Pakete zu installieren.
.unitypackage
installieren
Laden Sie die Input SDK-Unitypackage-Datei mit allen Abhängigkeiten herunter. Sie können .unitypackage
installieren, indem Sie Assets > Paket importieren > Benutzerdefiniertes Paket auswählen und nach der heruntergeladenen Datei suchen.
Mit UPM installieren
Alternativ können Sie das Paket mit dem Unity's Package Manager installieren. Laden Sie dazu die .tgz
herunter und installieren Sie die zugehörigen Abhängigkeiten:
- com.google.external-dependency-manager-1.2.172
- com.google.librarywrapper.java-0.2.0
- com.google.librarywrapper.openjdk8-0.2.0
- com.google.android.library.play.games.inputmapping-1.1.0-beta
Mit OpenUPM installieren
Sie können das Paket mit OpenUPM installieren.
$ openupm add com.google.android.libraries.play.games.inputmapping
Beispielspiele
Beispiele für die Integration mit dem Input SDK finden Sie unter AGDK-Tunnel für Kotlin- oder Java-Spiele und Trivial Kart für Unity-Spiele.
Schlüsselbindungen generieren
Registrieren Sie Ihre Schlüsselbindungen, indem Sie ein InputMap
erstellen und mit einem InputMappingProvider
zurückgeben. Im folgenden Beispiel wird ein InputMappingProvider
dargestellt:
Kotlin
class InputSDKProvider : InputMappingProvider { override fun onProvideInputMap(): InputMap { TODO("Not yet implemented") } }
Java
public class InputSDKProvider implements InputMappingProvider { private static final String INPUTMAP_VERSION = "1.0.0"; @Override @NonNull public InputMap onProvideInputMap() { // TODO: return an InputMap } }
C#
#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 InputSDKProvider : InputMappingProviderCallbackHelper { public static readonly string INPUT_MAP_VERSION = "1.0.0"; public override InputMap OnProvideInputMap() { // TODO: return an InputMap } } #endif
Eingabeaktionen definieren
Mit der Klasse InputAction
wird einer Spielaktion ein Schlüssel oder eine Schlüsselkombination zugeordnet. InputActions
muss in allen InputActions
eindeutige IDs haben.
Wenn Sie die Neuzuordnung unterstützen, können Sie definieren, welche InputActions
neu zugeordnet werden können. Wenn Ihr Spiel Neuzuordnungen nicht unterstützt, sollten Sie die Option für die Neuzuordnung für alle InputActions
deaktivieren. Das Input SDK ist jedoch so intelligent, dass die Neuzuordnung deaktiviert wird, wenn sie in InputMap
nicht unterstützt wird.
In diesem Beispiel wird der Schlüssel
Kotlin
companion object { private val driveInputAction = InputAction.create( "Drive", InputActionsIds.DRIVE.ordinal.toLong(), InputControls.create(listOf(KeyEvent.KEYCODE_SPACE), emptyList()), InputEnums.REMAP_OPTION_ENABLED) }
Java
private static final InputAction driveInputAction = InputAction.create( "Drive", InputEventIds.DRIVE.ordinal(), InputControls.create( Collections.singletonList(KeyEvent.KEYCODE_SPACE), Collections.emptyList()), InputEnums.REMAP_OPTION_ENABLED );
C#
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 );
Aktionen können auch Mauseingaben darstellen. In diesem Beispiel wird Linksklick auf die Aktion Verschieben festgelegt:
Kotlin
companion object { private val mouseInputAction = InputAction.create( "Move", InputActionsIds.MOUSE_MOVEMENT.ordinal.toLong(), InputControls.create(emptyList(), listOf(InputControls.MOUSE_LEFT_CLICK)), InputEnums.REMAP_OPTION_DISABLED) }
Java
private static final InputAction mouseInputAction = InputAction.create( "Move", InputActionsIds.MOUSE_MOVEMENT.ordinal(), InputControls.create( Collections.emptyList(), Collections.singletonList(InputControls.MOUSE_LEFT_CLICK) ), InputEnums.REMAP_OPTION_DISABLED );
C#
private static readonly InputAction mouseInputAction = InputAction.Create( "Move", (long)InputEventIds.MOUSE_MOVEMENT, InputControls.Create( new ArrayList<Integer>(), new[] { new Integer((int)PlayMouseAction.MouseLeftClick) }.ToJavaList() ), InputEnums.REMAP_OPTION_DISABLED );
Für Tastenkombinationen werden mehrere Schlüsselcodes an die InputAction
übergeben. In diesem Beispiel wird
Kotlin
companion object { private val turboInputAction = InputAction.create( "Turbo", InputActionsIds.TURBO.ordinal.toLong(), InputControls.create( listOf(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SPACE), emptyList()), InputEnums.REMAP_OPTION_ENABLED) }
Java
private static final InputAction turboInputAction = InputAction.create( "Turbo", InputActionsIds.TURBO.ordinal(), InputControls.create( Arrays.asList(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SPACE), Collections.emptyList() ), InputEnums.REMAP_OPTION_ENABLED );
C#
private static readonly InputAction turboInputAction = InputAction.Create( "Turbo", (long)InputEventIds.TURBO, InputControls.Create( new[] { new Integer(AndroidKeyCode.KEYCODE_SHIFT_LEFT), new Integer(AndroidKeyCode.KEYCODE_SPACE) }.ToJavaList(), new ArrayList<Integer>()), InputEnums.REMAP_OPTION_ENABLED );
Mit dem Input SDK können Sie Maus- und Tastentasten zu einer einzigen Aktion kombinieren. Dieses Beispiel zeigt an, dass durch gleichzeitiges Drücken von
Kotlin
companion object { private val addWaypointInputAction = InputAction.create( "Add waypoint", InputActionsIds.ADD_WAYPOINT.ordinal.toLong(), InputControls.create( listOf(KeyEvent.KeyEvent.KEYCODE_TAB), listOf(InputControls.MOUSE_RIGHT_CLICK)), InputEnums.REMAP_OPTION_DISABLED) }
Java
private static final InputAction addWaypointInputAction = InputAction.create( "Add waypoint", InputActionsIds.ADD_WAYPOINT.ordinal(), InputControls.create( Collections.singletonList(KeyEvent.KEYCODE_TAB), Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK) ), InputEnums.REMAP_OPTION_DISABLED );
C#
private static readonly InputAction addWaypointInputAction = InputAction.Create( "Add waypoint", (long)InputEventIds.ADD_WAYPOINT, InputControls.Create( new[] { new Integer(AndroidKeyCode.KEYCODE_SPACE) }.ToJavaList(), new[] { new Integer((int)PlayMouseAction.MouseRightClick) }.ToJavaList() ), InputEnums.REMAP_OPTION_DISABLED );
InputAction enthält die folgenden Felder:
ActionLabel
: String, der in der UI für diese Aktion angezeigt wird. Die Lokalisierung erfolgt nicht automatisch. Sie sollten sie daher vorab durchführen.InputControls
: definiert die Eingabesteuerelemente, die von dieser Aktion verwendet werden. Die Steuerelemente werden konsistenten Symbolen im Overlay zugeordnet.InputActionId
:InputIdentifier
-Objekt, in dem die Nummern-ID und die Version vonInputAction
gespeichert sind. Weitere Informationen finden Sie unter Tracking-Schlüssel-IDs.InputRemappingOption
: entwederInputEnums.REMAP_OPTION_ENABLED
oderInputEnums.REMAP_OPTION_DISABLED
. Definiert, ob die Aktion für die Neuzuordnung aktiviert wird. Wenn Ihr Spiel keine Neuzuordnungen unterstützt, können Sie dieses Feld überspringen oder es einfach deaktivieren.RemappedInputControls
: schreibgeschütztesInputControls
-Objekt zum Lesen des neu zugeordneten Schlüssels, der vom Nutzer bei der Neuzuordnung von Ereignissen festgelegt wurde. Wird verwendet, um Benachrichtigungen über Neuzuordnungen von Ereignissen zu erhalten.
InputControls
steht für die einer Aktion zugeordneten Eingaben und enthält die folgenden Felder:
AndroidKeycodes
: ist eine Liste von Ganzzahlen, die die Tastatureingaben für eine Aktion darstellen. Diese werden in der Klasse KeyEvent oder der Klasse AndroidKeycode für Unity definiert.MouseActions
: ist eine Liste vonMouseAction
-Werten, die Mauseingaben für diese Aktion darstellen.
Eingabegruppen definieren
InputActions
werden mithilfe von InputGroups
mit logisch zusammenhängenden Aktionen gruppiert, um die Navigation zu verbessern und die Sichtbarkeit im Overlay zu steuern. Jede InputGroup
-ID muss in allen InputGroups
in deinem Spiel eindeutig sein.
Wenn Sie Ihre Eingabeaktionen in Gruppen organisieren, können Spieler leichter die richtige Tastenkombination für ihren aktuellen Kontext finden.
Wenn Sie die Neuzuordnung unterstützen, können Sie definieren, welche InputGroups
neu zugeordnet werden können. Wenn Ihr Spiel Neuzuordnungen nicht unterstützt, sollten Sie die Option für die Neuzuordnung für alle InputGroups
deaktivieren. Das Input SDK ist jedoch so intelligent, dass die Neuzuordnung deaktiviert wird, wenn sie in InputMap
nicht unterstützt wird.
Kotlin
companion object { private val menuInputGroup = InputGroup.create( "Menu keys", listOf( navigateUpInputAction, navigateLeftInputAction, navigateDownInputAction, navigateRightInputAction, openMenuInputAction, returnMenuInputAction), InputGroupsIds.MENU_ACTION_KEYS.ordinal.toLong(), InputEnums.REMAP_OPTION_ENABLED ) }
Java
private static final InputGroup menuInputGroup = InputGroup.create( "Menu keys", Arrays.asList( navigateUpInputAction, navigateLeftInputAction, navigateDownInputAction, navigateRightInputAction, openMenuInputAction, returnMenuInputAction), InputGroupsIds.MENU_ACTION_KEYS.ordinal(), REMAP_OPTION_ENABLED );
C#
private static readonly InputGroup menuInputGroup = InputGroup.Create( "Menu keys", new[] { navigateUpInputAction, navigateLeftInputAction, navigateDownInputAction, navigateRightInputAction, openMenuInputAction, returnMenuInputAction, }.ToJavaList(), (long)InputGroupsIds.MENU_ACTION_KEYS, InputEnums.REMAP_OPTION_ENABLED );
Im folgenden Beispiel werden die Eingabegruppen Straßensteuerelemente und Menüsteuerelemente im Overlay angezeigt:
InputGroup
enthält die folgenden Felder:
GroupLabel
: Ein String, der im Overlay angezeigt wird und mit dem eine Reihe von Aktionen logisch gruppiert werden kann. Dieser String wird nicht automatisch lokalisiert.InputActions
: eine Liste derInputAction
-Objekte, die Sie im vorherigen Schritt definiert haben. All diese Aktionen werden unter der Überschrift der Gruppe angezeigt.InputGroupId
:InputIdentifier
-Objekt, in dem die Nummern-ID und die Version vonInputGroup
gespeichert sind. Weitere Informationen finden Sie unter Tracking-Schlüssel-IDs.InputRemappingOption
: entwederInputEnums.REMAP_OPTION_ENABLED
oderInputEnums.REMAP_OPTION_DISABLED
. Wenn diese Option deaktiviert ist, ist die Neuzuordnung für alleInputAction
-Objekte in dieser Gruppe deaktiviert, selbst wenn deren Option für die Neuzuordnung aktiviert ist. Wenn diese Option aktiviert ist, können alle Aktionen, die zu dieser Gruppe gehören, neu zugeordnet werden können, sofern dies nicht durch die einzelnen Aktionen deaktiviert wurde.
Eingabekontexte definieren
Mit InputContexts
kann dein Spiel unterschiedliche Tastatursteuerelemente für verschiedene Szenen deines Spiels verwenden. Beispiele:
- Sie können für Navigationsmenüs andere Sätze von Eingaben angeben als für das Bewegen im Spiel.
- Je nach Fortbewegungsmodus in Ihrem Spiel können Sie verschiedene Gruppen von Eingaben angeben, z. B. Autofahren oder Gehen.
- Sie können je nach aktuellem Spielstand unterschiedliche Sätze von Eingaben angeben, z. B. das Navigieren durch eine Überwelt oder das Spielen eines einzelnen Levels.
Bei Verwendung von InputContexts
werden im Overlay zuerst die Gruppen des verwendeten Kontexts angezeigt. Wenn Sie dieses Verhalten aktivieren möchten, rufen Sie setInputContext()
auf. Damit wird der Kontext immer dann festgelegt, wenn Ihr Spiel eine andere Szene beginnt. Das wird in der folgenden Abbildung veranschaulicht: Beim Fahren sind die Aktionen der Straßensteuerelemente oben im Overlay zu sehen. Beim Öffnen des Menüs „Shop“ sind die Aktionen für die Menüsteuerelemente oben im Overlay zu sehen.
Um diese Overlay-Updates zu aktualisieren, legst du an verschiedenen Punkten im Spiel eine andere InputContext
fest. Aktion:
InputActions
mithilfe vonInputGroups
mit logisch zusammenhängenden Aktionen gruppieren- Weisen Sie diese
InputGroups
einemInputContext
für die verschiedenen Teile Ihres Spiels zu.
InputGroups
, die zum selben InputContext
gehören, dürfen keine widersprüchlichen InputActions
haben, wenn derselbe Schlüssel verwendet wird. Es empfiehlt sich, jede InputGroup
einer einzelnen InputContext
zuzuweisen.
Der folgende Beispielcode veranschaulicht die InputContext
-Logik:
Kotlin
companion object { val menuSceneInputContext = InputContext.create( "Menu", InputIdentifier.create( INPUTMAP_VERSION, InputContextIds.MENU_SCENE.ordinal.toLong()), listOf(basicMenuNavigationInputGroup, menuActionsInputGroup)) val gameSceneInputContext = InputContext.create( "Game", InputIdentifier.create( INPUTMAP_VERSION, InputContextIds.GAME_SCENE.ordinal.toLong()), listOf( movementInputGroup, mouseActionsInputGroup, emojisInputGroup, gameActionsInputGroup)) }
Java
public static final InputContext menuSceneInputContext = InputContext.create( "Menu", InputIdentifier.create( INPUTMAP_VERSION, InputContextIds.MENU_SCENE.ordinal()), Arrays.asList( basicMenuNavigationInputGroup, menuActionsInputGroup ) ); public static final InputContext gameSceneInputContext = InputContext.create( "Game", InputIdentifier.create( INPUTMAP_VERSION, InputContextIds.GAME_SCENE.ordinal()), Arrays.asList( movementInputGroup, mouseActionsInputGroup, emojisInputGroup, gameActionsInputGroup ) );
C#
public static readonly InputContext menuSceneInputContext = InputContext.Create( "Menu", InputIdentifier.Create( INPUT_MAP_VERSION, (long)InputContextsIds.MENU_SCENE), new[] { basicMenuNavigationInputGroup, menuActionsInputGroup }.ToJavaList() ); public static readonly InputContext gameSceneInputContext = InputContext.Create( "Game", InputIdentifier.Create( INPUT_MAP_VERSION, (long)InputContextsIds.GAME_SCENE), new[] { movementInputGroup, mouseActionsInputGroup, emojisInputGroup, gameActionsInputGroup }.ToJavaList() );
InputContext
enthält die folgenden Felder:
LocalizedContextLabel
: ein String, der die Gruppen beschreibt, die zum Kontext gehören.InputContextId
:InputIdentifier
-Objekt, in dem die Nummern-ID und die Version vonInputContext
gespeichert sind. Weitere Informationen finden Sie unter Tracking-Schlüssel-IDs.ActiveGroups
: Eine Liste vonInputGroups
, die verwendet und oben im Overlay angezeigt wird, wenn dieser Kontext aktiv ist.
Eingabezuordnung erstellen
Ein InputMap
ist eine Sammlung aller InputGroup
-Objekte, die in einem Spiel verfügbar sind. Daher sind alle InputAction
-Objekte, die ein Spieler erwarten kann, zusammengefasst.
Wenn du deine Schlüsselbindungen meldest, erstellst du ein InputMap
mit allen in deinem Spiel verwendeten InputGroups
.
Wenn Ihr Spiel keine Neuzuordnungen unterstützt, deaktivieren Sie die Option für die Neuzuordnung und lassen Sie die reservierten Schlüssel leer.
Im folgenden Beispiel wird ein InputMap
erstellt, mit dem eine Sammlung von InputGroups
gemeldet wird.
Kotlin
companion object { val gameInputMap = InputMap.create( listOf( basicMenuNavigationInputGroup, menuActionKeysInputGroup, movementInputGroup, mouseMovementInputGroup, pauseMenuInputGroup), MouseSettings.create(true, false), InputIdentifier.create(INPUTMAP_VERSION, INPUT_MAP_ID.toLong()), InputEnums.REMAP_OPTION_ENABLED, // Use ESCAPE as reserved remapping key listof(InputControls.create(listOf(KeyEvent.KEYCODE_ESCAPE), emptyList())) ) }
Java
public static final InputMap gameInputMap = InputMap.create( Arrays.asList( basicMenuNavigationInputGroup, menuActionKeysInputGroup, movementInputGroup, mouseMovementInputGroup, pauseMenuInputGroup), MouseSettings.create(true, false), InputIdentifier.create(INPUTMAP_VERSION, INPUT_MAP_ID), REMAP_OPTION_ENABLED, // Use ESCAPE as reserved remapping key Arrays.asList( InputControls.create( Collections.singletonList(KeyEvent.KEYCODE_ESCAPE), Collections.emptyList() ) ) );
C#
public static readonly InputMap gameInputMap = InputMap.Create( new[] { basicMenuNavigationInputGroup, menuActionKeysInputGroup, movementInputGroup, mouseMovementInputGroup, pauseMenuInputGroup, }.ToJavaList(), MouseSettings.Create(true, false), InputIdentifier.Create(INPUT_MAP_VERSION, INPUT_MAP_ID), InputEnums.REMAP_OPTION_ENABLED, // Use ESCAPE as reserved remapping key new[] { InputControls.Create( New[] { new Integer(AndroidKeyCode.KEYCODE_ESCAPE) }.ToJavaList(), new ArrayList<Integer>()) }.ToJavaList() );
InputMap
enthält die folgenden Felder:
InputGroups
: die von deinem Spiel gemeldeten InputGroups. Die Gruppen werden im Overlay der Reihe nach angezeigt, sofern nicht die aktuellen Gruppen angegeben sind, die zum Aufrufen vonsetInputContext()
verwendet werden.MouseSettings
: DasMouseSettings
-Objekt gibt an, dass die Mausempfindlichkeit angepasst werden kann und dass die Maus um die y-Achse umgekehrt wird.InputMapId
:InputIdentifier
-Objekt, in dem die Nummern-ID und die Version vonInputMap
gespeichert sind. Weitere Informationen finden Sie unter Tracking-Schlüssel-IDs.InputRemappingOption
: entwederInputEnums.REMAP_OPTION_ENABLED
oderInputEnums.REMAP_OPTION_DISABLED
. Definiert, ob die Funktion für die Neuzuordnung aktiviert ist.ReservedControls
: eine Liste vonInputControls
, denen Nutzer nicht neu zuordnen dürfen.
Tracking-Schlüssel-IDs
Die Objekte InputAction
, InputGroup
, InputContext
und InputMap
enthalten ein InputIdentifier
-Objekt, das eine eindeutige Nummern-ID und eine String-Versions-ID speichert.
Das Tracking der Stringversion Ihrer Objekte ist optional, wird jedoch empfohlen, um die Versionen Ihrer InputMap
zu erfassen. Wenn keine Stringversion angegeben ist, ist der String leer. Für InputMap
-Objekte ist eine Stringversion erforderlich.
Im folgenden Beispiel wird InputActions
oder InputGroups
eine Stringversion zugewiesen:
Kotlin
class InputSDKProviderKotlin : InputMappingProvider { companion object { const val INPUTMAP_VERSION = "1.0.0" 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 ) private val movementInputGroup = InputGroup.create( "Basic movement", listOf( moveUpInputAction, moveLeftInputAction, moveDownInputAction, mouseGameInputAction), InputIdentifier.create( INPUTMAP_VERSION, InputGroupsIds.BASIC_MOVEMENT.ordinal.toLong()), InputEnums.REMAP_OPTION_ENABLED) } }
Java
public class InputSDKProvider implements InputMappingProvider { public static final String INPUTMAP_VERSION = "1.0.0"; private static final InputAction enterMenuInputAction = InputAction.create( "Enter menu", InputControls.create( Collections.singletonList(KeyEvent.KEYCODE_ENTER), Collections.emptyList()), InputIdentifier.create( INPUTMAP_VERSION, InputActionsIds.ENTER_MENU.ordinal()), InputEnums.REMAP_OPTION_ENABLED ); private static final InputGroup movementInputGroup = InputGroup.create( "Basic movement", Arrays.asList( moveUpInputAction, moveLeftInputAction, moveDownInputAction, moveRightInputAction, mouseGameInputAction ), InputIdentifier.create( INPUTMAP_VERSION, InputGroupsIds.BASIC_MOVEMENT.ordinal()), InputEnums.REMAP_OPTION_ENABLED ); }
C#
#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 enterMenuInputAction = InputAction.Create( "Enter menu", InputControls.Create( new[] { new Integer(AndroidKeyCode.KEYCODE_SPACE)}.ToJavaList(), new ArrayList<Integer>()), InputIdentifier.Create( INPUT_MAP_VERSION, (long)InputEventIds.ENTER_MENU), InputEnums.REMAP_OPTION_ENABLED ); private static readonly InputGroup movementInputGroup = InputGroup.Create( "Basic movement", new[] { moveUpInputAction, moveLeftInputAction, moveDownInputAction, moveRightInputAction, mouseGameInputAction }.ToJavaList(), InputIdentifier.Create( INPUT_MAP_VERSION, (long)InputGroupsIds.BASIC_MOVEMENT), InputEnums.REMAP_OPTION_ENABLED ); } #endif
Die IDs von InputAction
-Objekten müssen in allen InputActions
in Ihrer InputMap
eindeutig sein. Ebenso müssen InputGroup
-Objekt-IDs in allen InputGroups
in einem InputMap
eindeutig sein. Im folgenden Beispiel wird gezeigt, wie Sie mit einem enum
die eindeutigen IDs Ihres Objekts verfolgen:
Kotlin
enum class InputActionsIds { NAVIGATE_UP, NAVIGATE_DOWN, ENTER_MENU, EXIT_MENU, // ... JUMP, RUN, EMOJI_1, EMOJI_2, // ... } 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 } enum class InputContextIds { MENU_SCENE, // Basic menu navigation, menu actions GAME_SCENE, // Basic movement, mouse actions, emojis, game actions } const val INPUT_MAP_ID = 0
Java
public enum InputActionsIds { NAVIGATE_UP, NAVIGATE_DOWN, ENTER_MENU, EXIT_MENU, // ... JUMP, RUN, EMOJI_1, EMOJI_2, // ... } 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 } public enum InputContextIds { MENU_SCENE, // Basic navigation, menu actions GAME_SCENE, // Basic movement, mouse actions, emojis, game actions } public static final long INPUT_MAP_ID = 0;
C#
public enum InputActionsIds { NAVIGATE_UP, NAVIGATE_DOWN, ENTER_MENU, EXIT_MENU, // ... JUMP, RUN, EMOJI_1, EMOJI_2, // ... } 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 } public enum InputContextIds { MENU_SCENE, // Basic navigation, menu actions GAME_SCENE, // Basic movement, mouse actions, emojis, game actions } public static readonly long INPUT_MAP_ID = 0;
InputIdentifier
enthält die folgenden Felder:
UniqueId
: Eine eindeutige Nummern-ID, die einen bestimmten Satz von Eingabedaten eindeutig identifiziert.VersionString
: Ein menschenlesbarer Versionsstring, der festgelegt ist, um eine Version von Eingabedaten zwischen zwei Versionen von Eingabedatenänderungen zu identifizieren.
Benachrichtigung bei Neuzuordnung von Ereignissen erhalten (optional)
Du erhältst Benachrichtigungen zu Neuzuordnungsereignissen, um über die in deinem Spiel verwendeten Schlüssel informiert zu werden. Dadurch kann dein Spiel die Assets aktualisieren, die auf dem Spielbildschirm angezeigt werden, mit dem die Aktionssteuerung angezeigt wird.
Die folgende Abbildung zeigt ein Beispiel für dieses Verhalten, bei dem nach der Neuzuordnung der Schlüssel
Um diese Funktion zu nutzen, wird ein InputRemappingListener
-Callback registriert. Registrieren Sie zuerst eine InputRemappingListener
-Instanz, um diese Funktion zu implementieren:
Kotlin
class InputSDKRemappingListener : InputRemappingListener { override fun onInputMapChanged(inputMap: InputMap) { Log.i(TAG, "Received update on input map changed.") if (inputMap.inputRemappingOption() == InputEnums.REMAP_OPTION_DISABLED) { return } for (inputGroup in inputMap.inputGroups()) { if (inputGroup.inputRemappingOption() == InputEnums.REMAP_OPTION_DISABLED) { continue } for (inputAction in inputGroup.inputActions()) { if (inputAction.inputRemappingOption() != InputEnums.REMAP_OPTION_DISABLED) { // Found InputAction remapped by user processRemappedAction(inputAction) } } } } private fun processRemappedAction(remappedInputAction: InputAction) { // Get remapped action info val remappedControls = remappedInputAction.remappedInputControls() val remappedKeyCodes = remappedControls.keycodes() val mouseActions = remappedControls.mouseActions() val version = remappedInputAction.inputActionId().versionString() val remappedActionId = remappedInputAction.inputActionId().uniqueId() val currentInputAction: Optional<InputAction> currentInputAction = if (version == null || version.isEmpty() || version == InputSDKProvider.INPUTMAP_VERSION ) { getCurrentVersionInputAction(remappedActionId) } else { Log.i(TAG, "Detected version of user-saved input action defers from current version") getCurrentVersionInputActionFromPreviousVersion( remappedActionId, version) } if (!currentInputAction.isPresent) { Log.e(TAG, String.format( "can't find remapped input action with id %d and version %s", remappedActionId, if (version == null || version.isEmpty()) "UNKNOWN" else version)) return } val originalControls = currentInputAction.get().inputControls() val originalKeyCodes = originalControls.keycodes() Log.i(TAG, String.format( "Found input action with id %d remapped from key %s to key %s", remappedActionId, keyCodesToString(originalKeyCodes), keyCodesToString(remappedKeyCodes))) // TODO: make display changes to match controls used by the user } private fun getCurrentVersionInputAction(inputActionId: Long): Optional<InputAction> { for (inputGroup in InputSDKProvider.gameInputMap.inputGroups()) { for (inputAction in inputGroup.inputActions()) { if (inputAction.inputActionId().uniqueId() == inputActionId) { return Optional.of(inputAction) } } } return Optional.empty() } private fun getCurrentVersionInputActionFromPreviousVersion( inputActionId: Long, previousVersion: String ): Optional<InputAction7gt; { // TODO: add logic to this method considering the diff between the current and previous // InputMap. return Optional.empty() } private fun keyCodesToString(keyCodes: List<Int>): String { val builder = StringBuilder() for (keyCode in keyCodes) { if (!builder.toString().isEmpty()) { builder.append(" + ") } builder.append(keyCode) } return String.format("(%s)", builder) } companion object { private const val TAG = "InputSDKRemappingListener" } }
Java
public class InputSDKRemappingListener implements InputRemappingListener { private static final String TAG = "InputSDKRemappingListener"; @Override public void onInputMapChanged(InputMap inputMap) { Log.i(TAG, "Received update on input map changed."); if (inputMap.inputRemappingOption() == InputEnums.REMAP_OPTION_DISABLED) { return; } for (InputGroup inputGroup : inputMap.inputGroups()) { if (inputGroup.inputRemappingOption() == InputEnums.REMAP_OPTION_DISABLED) { continue; } for (InputAction inputAction : inputGroup.inputActions()) { if (inputAction.inputRemappingOption() != InputEnums.REMAP_OPTION_DISABLED) { // Found InputAction remapped by user processRemappedAction(inputAction); } } } } private void processRemappedAction(InputAction remappedInputAction) { // Get remapped action info InputControls remappedControls = remappedInputAction.remappedInputControls(); List<Integer> remappedKeyCodes = remappedControls.keycodes(); List<Integer> mouseActions = remappedControls.mouseActions(); String version = remappedInputAction.inputActionId().versionString(); long remappedActionId = remappedInputAction.inputActionId().uniqueId(); Optional<InputAction> currentInputAction; if (version == null || version.isEmpty() || version.equals(InputSDKProvider.INPUTMAP_VERSION)) { currentInputAction = getCurrentVersionInputAction(remappedActionId); } else { Log.i(TAG, "Detected version of user-saved input action defers " + "from current version"); currentInputAction = getCurrentVersionInputActionFromPreviousVersion( remappedActionId, version); } if (!currentInputAction.isPresent()) { Log.e(TAG, String.format( "input action with id %d and version %s not found", remappedActionId, version == null || version.isEmpty() ? "UNKNOWN" : version)); return; } InputControls originalControls = currentInputAction.get().inputControls(); List<Integer> originalKeyCodes = originalControls.keycodes(); Log.i(TAG, String.format( "Found input action with id %d remapped from key %s to key %s", remappedActionId, keyCodesToString(originalKeyCodes), keyCodesToString(remappedKeyCodes))); // TODO: make display changes to match controls used by the user } private Optional<InputAction> getCurrentVersionInputAction( long inputActionId) { for (InputGroup inputGroup : InputSDKProvider.gameInputMap.inputGroups()) { for (InputAction inputAction : inputGroup.inputActions()) { if (inputAction.inputActionId().uniqueId() == inputActionId) { return Optional.of(inputAction); } } } return Optional.empty(); } private Optional<InputAction> getCurrentVersionInputActionFromPreviousVersion( long inputActionId, String previousVersion) { // TODO: add logic to this method considering the diff between your // current and previous InputMap. return Optional.empty(); } private String keyCodesToString(List<Integer> keyCodes) { StringBuilder builder = new StringBuilder(); for (Integer keyCode : keyCodes) { if (!builder.toString().isEmpty()) { builder.append(" + "); } builder.append(keyCode); } return String.format("(%s)", builder); } }
C#
#if PLAY_GAMES_PC using System.Text; using Java.Lang; using Java.Util; using Google.Android.Libraries.Play.Games.Inputmapping; using Google.Android.Libraries.Play.Games.Inputmapping.Datamodel; using UnityEngine; public class InputSDKRemappingListener : InputRemappingListenerCallbackHelper { public override void OnInputMapChanged(InputMap inputMap) { Debug.Log("Received update on remapped controls."); if (inputMap.InputRemappingOption() == InputEnums.REMAP_OPTION_DISABLED) { return; } List<InputGroup> inputGroups = inputMap.InputGroups(); for (int i = 0; i < inputGroups.Size(); i ++) { InputGroup inputGroup = inputGroups.Get(i); if (inputGroup.InputRemappingOption() == InputEnums.REMAP_OPTION_DISABLED) { continue; } List<InputAction> inputActions = inputGroup.InputActions(); for (int j = 0; j < inputActions.Size(); j ++) { InputAction inputAction = inputActions.Get(j); if (inputAction.InputRemappingOption() != InputEnums.REMAP_OPTION_DISABLED) { // Found action remapped by user ProcessRemappedAction(inputAction); } } } } private void ProcessRemappedAction(InputAction remappedInputAction) { InputControls remappedInputControls = remappedInputAction.RemappedInputControls(); List<Integer> remappedKeycodes = remappedInputControls.Keycodes(); List<Integer> mouseActions = remappedInputControls.MouseActions(); string version = remappedInputAction.InputActionId().VersionString(); long remappedActionId = remappedInputAction.InputActionId().UniqueId(); InputAction currentInputAction; if (string.IsNullOrEmpty(version) || string.Equals( version, InputSDKMappingProvider.INPUT_MAP_VERSION)) { currentInputAction = GetCurrentVersionInputAction(remappedActionId); } else { Debug.Log("Detected version of used-saved input action defers" + " from current version"); currentInputAction = GetCurrentVersionInputActionFromPreviousVersion( remappedActionId, version); } if (currentInputAction == null) { Debug.LogError(string.Format( "Input Action with id {0} and version {1} not found", remappedActionId, string.IsNullOrEmpty(version) ? "UNKNOWN" : version)); return; } InputControls originalControls = currentInputAction.InputControls(); List<Integer> originalKeycodes = originalControls.Keycodes(); Debug.Log(string.Format( "Found Input Action with id {0} remapped from key {1} to key {2}", remappedActionId, KeyCodesToString(originalKeycodes), KeyCodesToString(remappedKeycodes))); // TODO: update HUD according to the controls of the user } private InputAction GetCurrentVersionInputAction( long inputActionId) { List<InputGroup> inputGroups = InputSDKMappingProvider.gameInputMap.InputGroups(); for (int i = 0; i < inputGroups.Size(); i++) { InputGroup inputGroup = inputGroups.Get(i); List<InputAction> inputActions = inputGroup.InputActions(); for (int j = 0; j < inputActions.Size(); j++) { InputAction inputAction = inputActions.Get(j); if (inputAction.InputActionId().UniqueId() == inputActionId) { return inputAction; } } } return null; } private InputAction GetCurrentVersionInputActionFromPreviousVersion( long inputActionId, string version) { // TODO: add logic to this method considering the diff between your // current and previous InputMap. return null; } private string KeyCodesToString(List<Integer> keycodes) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < keycodes.Size(); i ++) { Integer keycode = keycodes.Get(i); if (builder.Length > 0) { builder.Append(" + "); } builder.Append(keycode.IntValue()); } return string.Format("({0})", builder.ToString()); } } #endif
Der InputRemappingListener
wird beim Start nach dem Laden der vom Nutzer gespeicherten neu zugeordneten Steuerelemente und jedes Mal benachrichtigt, wenn der Nutzer seine Schlüssel neu zuordnet.
Initialisierung
Wenn Sie InputContexts
verwenden, legen Sie den Kontext bei jedem Übergang zu einer neuen Szene fest, einschließlich des ersten Kontexts, der für Ihre ursprüngliche Szene verwendet wird. Sie müssen die InputContext
festlegen, nachdem Sie InputMap
registriert haben.
Wenn Sie InputRemappingListeners
verwenden, um über Neuzuordnungen von Ereignissen benachrichtigt zu werden, registrieren Sie Ihre InputRemappingListener
, bevor Sie Ihre InputMappingProvider
registrieren. Andernfalls kann Ihr Spiel während der Startzeit wichtige Ereignisse verpassen.
Im folgenden Beispiel wird gezeigt, wie die API initialisiert wird:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (isGooglePlayGamesOnPC()) { val inputMappingClient = Input.getInputMappingClient(this) // Register listener before registering the provider inputMappingClient.registerRemappingListener(InputSDKRemappingListener()) inputMappingClient.setInputMappingProvider( InputSDKProvider()) // Set the context after you have registered the provider. inputMappingClient.setInputContext(InputSDKProvider.menuSceneInputContext) } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (isGooglePlayGamesOnPC()) { InputMappingClient inputMappingClient = Input.getInputMappingClient(this); // Register listener before registering the provider inputMappingClient.registerRemappingListener( new InputSDKRemappingListener()); inputMappingClient.setInputMappingProvider( new InputSDKProvider()); // Set the context after you have registered the provider inputMappingClient.setInputContext(InputSDKProvider.menuSceneInputContext); } }
C#
#if PLAY_GAMES_PC using Google.Android.Libraries.Play.Games.Inputmapping; using Google.Android.Libraries.Play.Games.InputMapping.ExternalType.Android.Content; using Google.LibraryWrapper.Java; #endif public class GameManager : MonoBehaviour { #if PLAY_GAMES_PC private InputSDKMappingProvider _inputMapProvider = new InputSDKMappingProvider(); private InputMappingClient _inputMappingClient; #endif public void Awake() { #if PLAY_GAMES_PC Context context = (Context)Utils.GetUnityActivity().GetRawObject(); _inputMappingClient = Google.Android.Libraries.Play.Games.Inputmapping .Input.GetInputMappingClient(context); // Register listener before registering the provider. _inputMappingClient.RegisterRemappingListener( new InputSDKRemappingListener()); _inputMappingClient.SetInputMappingProvider(_inputMapProvider); // Register context after you have registered the provider. _inputMappingClient.SetInputContext( InputSDKMappingProvider.menuSceneInputContext); #endif } }
Aufräumen
Heben Sie die Registrierung Ihrer InputMappingProvider
-Instanz und aller InputRemappingListener
-Instanzen auf, wenn das Spiel geschlossen ist. Das Input SDK ist jedoch intelligent genug, um die Offenlegung von Ressourcen zu vermeiden, wenn Sie das nicht tun:
Kotlin
override fun onDestroy() { if (isGooglePlayGamesOnPC()) { val inputMappingClient = Input.getInputMappingClient(this) inputMappingClient.clearInputMappingProvider() inputMappingClient.clearRemappingListener() } super.onDestroy() }
Java
@Override protected void onDestroy() { if (isGooglePlayGamesOnPC()) { InputMappingClient inputMappingClient = Input.getInputMappingClient(this); inputMappingClient.clearInputMappingProvider(); inputMappingClient.clearRemappingListener(); } super.onDestroy(); }
C#
public class GameManager : MonoBehaviour { private void OnDestroy() { #if PLAY_GAMES_PC _inputMappingClient.ClearInputMappingProvider(); _inputMappingClient.ClearRemappingListener(); #endif } }
Test
Sie können Ihre Input SDK-Implementierung testen, indem Sie das Overlay manuell öffnen, um das Spielerlebnis zu sehen, oder über die ADB-Shell für automatisierte Tests und Überprüfungen.
Der Emulator für Google Play Spiele auf dem PC prüft die Richtigkeit Ihrer Eingabezuordnung auf häufige Fehler. Für Szenarien wie doppelte eindeutige IDs, die Verwendung unterschiedlicher Eingabezuordnungen oder Fehler bei den Regeln für die Neuzuordnung (wenn die Neuzuordnung aktiviert ist), wird im Overlay eine Fehlermeldung wie unten angezeigt:
Prüfen Sie Ihre Input SDK-Implementierung mithilfe von adb
in der Befehlszeile.
Verwenden Sie den folgenden adb shell
-Befehl, um die aktuelle Eingabezuordnung zu erhalten. Ersetzen Sie dabei MY.PACKAGE.NAME
durch den Namen Ihres Spiels:
adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME
Wenn Sie InputMap
erfolgreich registriert haben, sieht die Ausgabe in etwa so aus:
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
}
Lokalisierung
Das Input SDK verwendet nicht das Lokalisierungssystem von Android. Deshalb musst du lokalisierte Strings angeben, wenn du ein InputMap
einreichst. Sie können auch das Lokalisierungssystem Ihrer Spiel-Engine verwenden.
Proguard
Wenn Sie Ihr Spiel mit Proguard komprimieren, fügen Sie der Proguard-Konfigurationsdatei die folgenden Regeln hinzu, damit das SDK nicht aus dem endgültigen Paket entfernt wird:
-keep class com.google.android.libraries.play.hpe.** { *; }
-keep class com.google.android.libraries.play.games.inputmapping.** { *; }
Nächste Schritte
Nachdem du das Input SDK in dein Spiel integriert hast, kannst du mit allen verbleibenden Anforderungen für Google Play Spiele auf dem PC fortfahren. Weitere Informationen findest du unter Erste Schritte mit Google Play Spiele auf dem PC.