Erste Schritte mit dem Input SDK

In diesem Dokument wird beschrieben, wie Sie das Input SDK in Spiele, die Google Play Spiele auf dem PC unterstützen. Zu den Aufgaben gehört das Hinzufügen des SDK zu Ihrem Spiel hinzufügen und eine Eingabe-Map generieren, die die Zuweisungen von Spielaktionen an Nutzereingaben.

Vorbereitung

Bevor du deinem Spiel das Input SDK hinzufügst, musst du Tastatur- und Mauseingabe über die Eingabesystem.

Das Input SDK stellt Google Play Spiele auf dem PC Informationen zu welche Einstellungen Ihr Spiel nutzt, damit sie dem Nutzer angezeigt werden können. Es kann auch optional eine Neuzuordnung der Tastatur für Nutzer zulassen.

Jedes Steuerelement ist ein InputAction (z.B. „J“ für „Jump“) und Sie organisieren Ihre InputActions in InputGroups. Ein InputGroup kann eine andere Modus in deinem Spiel, z. B. „Auto“ oder „Zu Fuß“ oder „Hauptmenü“. Sie können auch Verwenden Sie InputContexts, um anzugeben, welche Gruppen an verschiedenen Punkten für das Spiel.

Sie können die Tastaturneuzuordnungen automatisch aktivieren lassen. Ihre eigene Schnittstelle für die Neuzuordnung der Steuerelemente vorstellen möchten, können Sie diese Neuzuordnung des Eingabe-SDK.

Im folgenden Sequenzdiagramm wird die Funktionsweise der API des Input SDK beschrieben:

Sequenzdiagramm einer Spieleimplementierung, die die Input SDK API aufruft
und die Interaktion mit Android
.

Wenn das Input SDK in deinem Spiel implementiert ist, werden deine Steuerelemente angezeigt im Overlay für Google Play Spiele auf dem PC.

Das Overlay für Google Play Spiele auf dem PC

Das Overlay für Google Play Spiele auf dem PC („Overlay“) zeigt die Steuerelemente durch Ihr Spiel definiert wird. Nutzer können jederzeit auf das Overlay zugreifen, und drücken Sie Umschalttaste + Tabulatortaste.

Das Overlay für Google Play Spiele auf dem PC.

Best Practices für das Entwerfen von Key Bindings

Berücksichtigen Sie beim Entwerfen Ihrer Schlüsselbindungen die folgenden Best Practices:

  • Gruppieren Sie InputActions in logisch zusammenhängende InputGroups, um die Leistung zu verbessern Navigation und Sichtbarkeit der Steuerelemente während des Spiels.
  • Weisen Sie jede InputGroup maximal einem InputContext zu. Ein feines Granulat Mit InputMap lässt sich die Navigation in den Einstellungen einfacher in des Overlays.
  • Erstelle eine InputContext für jeden Szenentyp deines Spiels. Normalerweise können Sie ein einzelnes InputContext-Element für alle Szenen. Verwende unterschiedliche InputContexts für beliebige Minispiele in deinem Spiel oder für für eine einzelne Szene.
  • Wenn zwei Aktionen dafür vorgesehen sind, denselben Schlüssel unter demselben InputContext, verwenden Sie den Labelstring wie „Interaktion / Abfeuern“.
  • Wenn zwei Schlüssel zur Bindung an denselben InputAction vorgesehen sind, verwenden Sie 2. verschiedene InputActions, die in deinem Spiel dieselbe Aktion ausführen. Sie können denselben Labelstring für InputActions verwenden, wobei die ID jedoch unterscheiden.
  • Wenn eine Modifikatortaste auf mehrere Tasten angewendet wird, sollten Sie eine einzelne InputAction durch die Modifikatortaste anstelle mehrerer InputActions-Elemente, die Modifikatortaste kombinieren. Beispiel: Verwenden Sie Umschalttaste und W, A, S, D. Umschalttaste + W, Umschalttaste + A, Umschalttaste + S, Umschalttaste + D).
  • Die Neuzuordnung der Eingabe wird automatisch deaktiviert, wenn der Nutzer in Text schreibt . Befolgen Sie die Best Practices für die Implementierung von Android-Textfeldern, um Damit Android Textfelder in deinem Spiel erkennen und neu zugeordnete Tasten verhindern kann sie nicht behindern. Wenn Ihr Spiel nicht konventionellen Text verwenden muss Felder, die Sie setInputContext() mit einem InputContext verwenden können, das ein leere Liste mit InputGroups, um die manuelle Neuzuordnung zu deaktivieren.
  • Wenn Ihr Spiel eine Neuzuordnung unterstützt, sollten Sie Ihre Tastenbindungen aktualisieren: vertraulicher Vorgang, der zu Konflikten mit den vom Nutzer gespeicherten Versionen führen kann. Vermeiden die IDs vorhandener Einstellungen nach Möglichkeit ändern.

Die Neuzuordnungsfunktion

Google Play Spiele auf dem PC unterstützt die Neuzuordnung der Tastatursteuerung auf Grundlage der Taste Bindungen, die Ihr Spiel mithilfe des Input SDK bereitstellt. Dies ist optional und vollständig deaktiviert werden können. Sie können beispielsweise eine eigene Tastatur bereitstellen. für die Neuzuordnungsschnittstelle. Um die Neuzuordnung für Ihr Spiel zu deaktivieren, die Neuzuordnungsoption für InputMap deaktiviert ist (siehe Erstellen Sie eine InputMap, um weitere Informationen zu erhalten.

Um auf diese Funktion zuzugreifen, müssen Nutzer das Overlay öffnen und dann auf die Aktion klicken die neu kartografiert werden sollen. Google Play Spiele auf dem PC nach jeder Neuzuordnung den Standardsteuerelementen, die Ihr Spiel erwartet erhalten, sodass Ihr Spiel nicht die Neuzuordnung des Spielers berücksichtigen muss. Ich kann optional die Assets aktualisieren, die zur Anzeige der Tastatursteuerelemente in indem Sie einen Callback für die Neuzuordnung von Ereignissen hinzufügen.

Versuchen, den Schlüssel neu zuzuordnen

Google Play Spiele auf dem PC speichert neu zugeordnete Steuerelemente lokal für jeden Nutzer, So bleibt die Kontrolle über alle Spielesitzungen hinweg erhalten. Diese Informationen werden gespeichert, auf Datenträger nur für die PC-Plattform und hat keine Auswirkungen auf die mobile Nutzererfahrung. Die Kontrolldaten werden gelöscht, sobald der Nutzer Google Play Spiele auf dem PC deinstalliert oder neu installiert. Diese Daten sind nicht dauerhaft über mehrere PC-Geräte hinweg gespeichert.

Um die Funktion zur Neuzuordnung in Ihrem Spiel zu unterstützen, sollten Sie die folgenden Einschränkungen vermeiden:

Einschränkungen bei der Neuzuordnung

Die Neuzuordnung von Funktionen kann in deinem Spiel deaktiviert werden, wenn die Tastenbelegungen der folgenden Fälle:

  • InputActions mit Mehrfachtasten, die nicht aus einer Modifikatortaste + a bestehen ohne Modifikatortaste. Shift + A ist beispielsweise gültig, aber A + B, Strg + Alt oder Umschalttaste + A + Tabulatortaste hingegen nicht.
  • InputMap enthält InputActions, InputGroups oder InputContexts mit wiederholten eindeutigen IDs.

Einschränkungen der Neuzuordnung

Berücksichtigen Sie beim Entwerfen der Tastenbindungen für die Neuzuordnung Folgendes: Einschränkungen:

  • Eine Neuzuordnung von Tastenkombinationen wird nicht unterstützt. Beispielsweise können Nutzende ordnen Sie Umschalttaste + A zu Strg + B oder A zu Umschalttaste + A zu.
  • Die Neuzuordnung wird für InputActions mit Maustasten nicht unterstützt. Für Beispiel: Umschalttaste + Rechtsklick kann nicht neu zugeordnet werden.

Testen Sie die Tastenzuordnung im Emulator für Google Play Spiele auf dem PC.

Du kannst die Funktion zur Neuzuordnung jederzeit im Emulator von Google Play Spiele auf dem PC aktivieren indem Sie den folgenden adb-Befehl ausführen:

adb shell dumpsys input_mapping_service --set RemappingFlagValue true

Das Overlay ändert sich wie in der folgenden Abbildung:

Das Overlay mit aktivierter Tastenneuzuordnung

SDK hinzufügen

Installieren Sie das Input SDK gemäß Ihrer Entwicklungsplattform.

Java und Kotlin

Rufen Sie das Input SDK für Java oder Kotlin ab, indem Sie Ihrem Datei build.gradle auf Modulebene:

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 mit allen Abhängigkeiten muss installiert werden. Es gibt mehrere Möglichkeiten, um die Pakete zu installieren.

.unitypackage installieren

Unitypackage-Datei für das Eingabe-SDK herunterladen mit all seinen Abhängigkeiten. Sie können .unitypackage installieren, indem Sie Assets > Paket importieren > Custom Package und Suchen der heruntergeladenen Datei.

Über UPM installieren

Alternativ können Sie das Paket mit der Unity's Package Manager von Laden Sie die .tgz herunter und installieren Sie die zugehörigen Abhängigkeiten:

Mit OpenUPM installieren

Sie können das Paket mit OpenUPM

$ 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 Trivial Kart für Unity-Spiele.

Schlüsselbindungen generieren

Registrieren Sie Ihre Schlüsselbindungen, indem Sie ein InputMap erstellen und mit einem InputMappingProvider. Im folgenden Beispiel wird ein InputMappingProvider:

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

Die Klasse InputAction wird verwendet, um einem Spiel einen Schlüssel oder eine Tastenkombination zuzuordnen Aktion ausführen. InputActions muss in allen InputActions eindeutige IDs haben.

Wenn Sie eine Neuzuordnung unterstützen, können Sie festlegen, was InputActions sein darf neu zugeordnet. Wenn Ihr Spiel keine Neuzuordnung unterstützt, sollten Sie eine entsprechende Einstellung Die Option ist für alle deine InputActions deaktiviert, aber das Input SDK ist intelligent genug, um die Neuzuordnung zu deaktivieren, falls Sie diese Funktion in Ihrem InputMap.

In diesem Beispiel wird die Leertaste der Aktion Drive zugeordnet.

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
);

Im Overlay wird InputAction mit einer einzelnen Taste angezeigt.

Aktionen können auch Mauseingaben darstellen. In diesem Beispiel wird für Linksklick Folgendes festgelegt: Verschieben:

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
);

Im Overlay angezeigte Eingabeaktion für Maus.

Tastenkombinationen werden angegeben, indem mehrere Schlüsselcodes an Ihre InputAction In diesem Beispiel wird space + shift die Aktion Turbo, die auch dann funktioniert, wenn der Gruppenbereich Drive zugeordnet 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
);

Im Overlay angezeigte Eingabeaktion mit mehreren Tasten.

Mit dem Input SDK können Sie Maus- und Tastentasten für ein mit nur einer Aktion. In diesem Beispiel werden Umschalttaste und Rechtsklick zusammengedrückt wird in diesem Beispielspiel ein Wegpunkt hinzugefügt:

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
);

Im Overlay angezeigte InputAction-Kombination aus Taste und Maus.

InputAction enthält die folgenden Felder:

  • ActionLabel: Der auf der Benutzeroberfläche angezeigte String, der diese Aktion darstellt. Die Lokalisierung erfolgt nicht automatisch. Führen Sie die Lokalisierung daher erst nach oben durch. vorne.
  • InputControls: Definiert die Eingabesteuerelemente, die von dieser Aktion verwendet werden. Die werden den Glyphen im Overlay einheitlich zugeordnet.
  • InputActionId: InputIdentifier-Objekt, das die Nummern-ID und Version speichert der InputAction (weitere Informationen unter Tracking-Schlüssel-IDs) Informationen).
  • InputRemappingOption: entweder InputEnums.REMAP_OPTION_ENABLED oder InputEnums.REMAP_OPTION_DISABLED Legt fest, ob die Aktion für neu zuordnen. Falls Ihr Spiel keine Neuzuordnung unterstützt, können Sie dieses Feld überspringen oder deaktivieren Sie sie einfach.
  • RemappedInputControls: schreibgeschütztes InputControls-Objekt zum Lesen des neu zugeordnete Taste, die vom Nutzer bei der Neuzuordnung von Ereignissen festgelegt wurde (wird für Benachrichtigungen zur Neuzuordnung von Ereignissen) erhalten.

InputControls steht für die mit einer Aktion verknüpften Eingaben und enthält die folgenden Feldern:

  • AndroidKeycodes: ist eine Liste von Ganzzahlen, die Tastatureingaben darstellen die mit einer Aktion verknüpft sind. Diese sind in den Schlüsselereignis oder die AndroidKeycode-Klasse für Unity.
  • MouseActions: ist eine Liste von MouseAction-Werten, die Mauseingaben darstellen die mit dieser Aktion verknüpft sind.

Eingabegruppen definieren

InputActions werden mit logisch verwandten Aktionen gruppiert, indem InputGroups verwendet wird, um die Auffindbarkeit von Navigation und Steuerelementen im Overlay verbessern. Jedes Die InputGroup-ID muss für alle InputGroups in deinem Spiel eindeutig sein.

Indem Sie Ihre Eingabeaktionen in Gruppen organisieren, erleichtern Sie es den Spielern, die richtige Tastenkombination für den aktuellen Kontext zu finden.

Wenn Sie eine Neuzuordnung unterstützen, können Sie festlegen, was InputGroups sein darf neu zugeordnet. Wenn Ihr Spiel keine Neuzuordnung unterstützt, sollten Sie eine entsprechende Einstellung Die Option ist für alle deine InputGroups deaktiviert, aber das Input SDK ist intelligent genug, um die Neuzuordnung zu deaktivieren, falls Sie diese Funktion in Ihrem InputMap.

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 sehen Sie die Steuerelemente für Straßen und die Menüsteuerelemente. Eingabegruppen im Overlay:

Das Overlay zeigt eine InputMap an, die die Straßensteuerelemente und die
Das Menü steuert die Eingabegruppen.

InputGroup enthält die folgenden Felder:

  • GroupLabel: ein im Overlay anzuzeigender String, mit dem eine Reihe von Aktionen logisch gruppieren. Dieser String wird nicht automatisch lokalisiert.
  • InputActions: eine Liste von InputAction-Objekten, die Sie im vorherigen Schritt definiert haben Schritt. Alle diese Aktionen werden unter der Gruppenüberschrift angezeigt.
  • InputGroupId: InputIdentifier-Objekt, das die Nummern-ID und Version von InputGroup. Weitere Informationen finden Sie unter Tracking-Schlüssel-IDs für erhalten Sie weitere Informationen.
  • InputRemappingOption: entweder InputEnums.REMAP_OPTION_ENABLED oder InputEnums.REMAP_OPTION_DISABLED Wenn diese Option deaktiviert ist, werden alle InputAction Für Objekte, die zu dieser Gruppe gehören, ist die Neuzuordnung deaktiviert, auch wenn sie Option für die Neuzuordnung aktiviert ist. Wenn aktiviert, werden alle Aktionen kann an diese Gruppe angepasst werden, es sei denn, die Person hat dies deaktiviert. Aktionen.

Eingabekontexte definieren

Mit InputContexts kann dein Spiel andere Tastatursteuerelemente verwenden, verschiedene Szenen deines Spiels zu unterscheiden. Beispiel:

  • Sie können für Navigationsmenüs andere Gruppen von Eingaben als für das Verschieben angeben im Spiel.
  • Du kannst je nach Fortbewegungsmodus unterschiedliche Arten von Eingaben angeben z. B. mit dem Auto oder zu Fuß.
  • Sie können je nach aktuellem Status Ihrer z. B. in einer Überwelt navigieren oder auf einem einzelnen Level spielen.

Bei Verwendung von InputContexts zeigt das Overlay zuerst die Gruppen des Kontexts an verwendet wird. Rufen Sie zum Aktivieren dieses Verhaltens setInputContext() auf, um den Parameter immer dann, wenn Ihr Spiel in eine andere Szene eintritt. In der folgenden Abbildung demonstriert das folgende Verhalten: die Straßensteuerung Aktionen oben im Overlay angezeigt. Beim Öffnen des „Shops“ das Menü „Menüsteuerelemente“ Aktionen oben im Overlay angezeigt.

InputContexts, der Gruppen im Overlay sortiert.

Diese Overlay-Aktualisierungen werden erreicht, indem ein anderer InputContext festgelegt wird unter Punkte in Ihrem Spiel. Ziel

  1. Gruppieren Sie InputActions mit logisch zusammenhängenden Aktionen mithilfe von InputGroups
  2. Weisen Sie diese InputGroups einer InputContext für die verschiedenen Teile von dein Spiel

InputGroups, die zum selben InputContext gehören, dürfen keine widersprüchlichen InputActions, wobei derselbe Schlüssel verwendet wird. Es empfiehlt sich, jedem einzelnen InputGroup zu einem einzelnen InputContext.

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.
  • InputContextId: InputIdentifier-Objekt, das die Nummern-ID und Version speichert der InputContext (weitere Informationen unter Tracking-Schlüssel-IDs) Informationen).
  • ActiveGroups: Eine Liste von InputGroups, die oben angezeigt werden sollen des Overlays, wenn dieser Kontext aktiv ist.

Eingabezuordnung erstellen

Eine InputMap ist eine Sammlung aller InputGroup-Objekte, die in einem Spiel und somit alle InputAction-Objekte, die ein Spieler erwarten kann ausführen können.

Wenn Sie Berichte zu Ihren Schlüsselbindungen erstellen, erstellen Sie eine InputMap mit allen InputGroups wurde in deinem Spiel verwendet.

Falls Ihr Spiel dies nicht unterstützt, deaktivieren Sie die Option die reservierten Schlüssel leer sind.

Im folgenden Beispiel wird eine InputMap erstellt, die verwendet wird, um eine Sammlung von InputGroups.

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 Ihrem Spiel gemeldeten InputGroups. Die Gruppen sind werden im Overlay der Reihe nach angezeigt, sofern die aktuellen Gruppen in rufe setInputContext() auf.
  • MouseSettings: Das MouseSettings-Objekt gibt an, dass die Mausempfindlichkeit angepasst werden kann und dass die Maus auf der Y-Achse invertiert ist.
  • InputMapId: InputIdentifier-Objekt, das die Nummern-ID und Version von InputMap (weitere Informationen unter Tracking-Schlüssel-IDs) Informationen).
  • InputRemappingOption: entweder InputEnums.REMAP_OPTION_ENABLED oder InputEnums.REMAP_OPTION_DISABLED Legt fest, ob die Neuzuordnungsfunktion aktiviert.
  • ReservedControls: eine Liste von InputControls, die Nutzer nicht verwenden dürfen zu ändern.

Schlüssel-IDs erfassen

Die Objekte InputAction, InputGroup, InputContext und InputMap enthalten Folgendes: InputIdentifier-Objekt, das eine eindeutige Nummern-ID und eine String-Versions-ID speichert. Das Tracking der Stringversion Ihrer Objekte ist optional, empfohlen wird jedoch für das Tracking. Versionen von InputMap Ist keine Stringversion angegeben, Zeichenfolge ist leer. Für InputMap-Objekte ist eine Stringversion erforderlich.

Im folgenden Beispiel wird eine Zeichenfolgenversion InputActions oder InputGroups:

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 Nummern-IDs von InputAction-Objekten müssen in allen InputActions-Objekten eindeutig sein Dein InputMap. Ebenso müssen InputGroup-Objekt-IDs eindeutig sein InputGroups in InputMap. Im folgenden Beispiel wird veranschaulicht, wie ein enum, um die eindeutigen IDs Ihres Objekts zu 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 Zahlen-ID, die festgelegt ist, um eine bestimmte Reihe von Eingaben eindeutig zu identifizieren von Daten zu unterscheiden.
  • VersionString: ein für Menschen lesbarer Versionsstring, der zur Identifizierung einer Version festgelegt ist zwischen zwei Versionen von Änderungen der Eingabedaten.

Benachrichtigungen bei Neuzuordnungen von Ereignissen erhalten (optional)

Benachrichtigungen zu Ereignissen zur Neuzuordnung erhalten, um über die verwendeten Schlüssel informiert zu werden für Ihr Spiel. Dadurch kann dein Spiel die auf dem Spielbildschirm angezeigten Assets aktualisieren zur Anzeige der Aktionssteuerungen.

Die folgende Abbildung zeigt ein Beispiel für dieses Verhalten. Nach der Neuzuordnung die Tasten G, P und S bis J, X und T, werden die UI-Elemente des Spiels auf die vom Nutzer festgelegten Schlüssel anzuzeigen.

UI, die auf Neuzuordnungsereignisse mit dem InputRemappingListener-Callback reagiert

Dies wird durch die Registrierung eines InputRemappingListener Callback des Nutzers an. Um diese Funktion zu implementieren, müssen Sie zunächst ein InputRemappingListener-Instanz:

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

InputRemappingListener wird nach dem Laden des Ereignisses zum Start benachrichtigt. neu zugeordnete Steuerelemente und nach jeder Neuzuordnung der Schlüssel durch den Nutzer.

Initialisierung

Wenn Sie InputContexts verwenden, legen Sie den Kontext für jedes zu einer neuen Szene wechseln, einschließlich des ersten Kontexts, Szene. Sie müssen die InputContext festlegen, nachdem Sie Ihr InputMap.

Wenn Sie InputRemappingListeners verwenden, um über die Neuzuordnung von Ereignissen benachrichtigt zu werden registrieren Sie Ihr InputRemappingListener, bevor Sie Ihr InputMappingProvider. Andernfalls kann dein Spiel während Markteinführung.

Das folgende Beispiel zeigt, 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
    }
}

Bereinigen

Registrierung der InputMappingProvider-Instanz und aller InputRemappingListener-Daten aufheben wenn Ihr Spiel geschlossen wird, obwohl das Input SDK intelligent Ressourcenlecks zu vermeiden, wenn Sie Folgendes 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 Overlay, um das Playererlebnis zu sehen, oder über die ADB-Shell für automatisierte Tests und Verifizierung.

Der Emulator für Google Play Spiele auf dem PC prüft die Richtigkeit deiner Eingabekarte häufige Fehler beheben. Für Szenarien wie doppelte eindeutige IDs mit unterschiedlichen Eingabezuordnungen oder Fehler bei den Neuzuordnungsregeln (wenn die Neuzuordnung aktiviert ist) gilt Folgendes: wird folgende Fehlermeldung angezeigt: Das Input SDK-Overlay.

Prüfen Sie Ihre Eingabe SDK-Implementierung mit adb in der Befehlszeile. Um die aktuelle Eingabezuordnung abzurufen, verwenden Sie den folgenden adb shell-Befehl (Ersetzen MY.PACKAGE.NAME durch den Namen Ihres Spiels):

adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME

Wenn Sie Ihr Konto erfolgreich registriert haben, 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
}

Lokalisierung

Das Input SDK verwendet nicht das Lokalisierungssystem von Android. Als angezeigt wird, musst du beim Einreichen eines InputMap lokalisierte Strings angeben. Ich das Lokalisierungssystem Ihrer Spiel-Engine nutzen.

ProGuard

Wenn Sie Ihr Spiel mit Proguard reduzieren, fügen Sie die folgenden Regeln zu Ihrem um sicherzustellen, dass das SDK nicht aus Ihrer Datei entfernt wird. endgültiges Paket:

-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 fortfahren mit allen verbleibenden Anforderungen für Google Play Spiele auf dem PC. Weitere Informationen Weitere Informationen finden Sie unter Erste Schritte mit Google Play Spiele auf dem PC.