Z tego dokumentu dowiesz się, jak skonfigurować i wyświetlać pakiet SDK do obsługi danych wejściowych w grach, które obsługują Gry Google Play na PC. Obejmują one dodanie pakietu SDK do gry i wygenerowanie mapy wejść, która zawiera przypisania działań w grze do danych wejściowych użytkownika.
Zanim rozpoczniesz
Zanim dodasz pakiet SDK do obsługi danych wejściowych do gry, musisz obsługiwać dane wejściowe z klawiatury i myszy za pomocą systemu wejściowego silnika gry.
Pakiet Input SDK przekazuje do Gier Google Play na PC informacje o tym, jakich elementów sterujących używa Twoja gra, aby można było wyświetlać je użytkownikowi. Opcjonalnie może też umożliwiać użytkownikom zmianę przypisania klawiszy.
Każdy element sterujący to InputAction (np. „J” w przypadku „Skoku”), a InputActions są uporządkowane w InputGroups. Symbol InputGroup może oznaczać inny tryb w grze, np. „Jazda”, „Chodzenie” lub „Menu główne”. Możesz też użyć InputContexts, aby wskazać, które grupy są aktywne w różnych momentach gry.
Możesz włączyć automatyczne mapowanie klawiatury, ale jeśli wolisz udostępnić własny interfejs mapowania sterowania, możesz wyłączyć mapowanie pakietu SDK do obsługi danych wejściowych.
Ten diagram sekwencji opisuje, jak działa interfejs API pakietu Input SDK:

Gdy Twoja gra zaimplementuje pakiet Input SDK, elementy sterujące będą wyświetlane w nakładce Gier Google Play na PC.
Nakładka Gier Google Play na PC
Nakładka Gier Google Play na PC („nakładka”) wyświetla elementy sterujące zdefiniowane przez Twoją grę. Użytkownicy mogą w dowolnym momencie otworzyć nakładkę, naciskając Shift + Tab.

Sprawdzone metody projektowania powiązań klawiszy
Podczas projektowania przypisań klawiszy pamiętaj o tych sprawdzonych metodach:
- Grupuj
InputActionsw logicznie powiązaneInputGroups, aby ułatwić poruszanie się po elementach sterujących i ich znajdowanie podczas rozgrywki. - Przypisz każdy element
InputGroupdo co najwyżej jednego elementuInputContext. Drobne ziarnoInputMapzapewnia lepsze wrażenia podczas poruszania się po elementach sterujących w nakładce. - Utwórz
InputContextdla każdego typu sceny w grze. Zwykle możesz użyć jednego taguInputContextdla wszystkich scen przypominających menu. Używaj różnychInputContextsw przypadku minigier w swojej grze lub alternatywnych elementów sterujących w jednej scenie. - Jeśli 2 działania mają używać tego samego klawisza w tym samym
InputContext, użyj ciągu etykiety, np. „Interakcja / Ogień”. - Jeśli 2 klucze mają być powiązane z tym samym
InputAction, użyj 2 różnychInputActions, które wykonują tę samą czynność w grze. Możesz użyć tego samego ciągu znaków etykiety w przypadku obu atrybutówInputActions, ale ich identyfikatory muszą być różne. - Jeśli klawisz modyfikujący jest stosowany do zestawu klawiszy, użyj pojedynczego klawisza
InputActionz klawiszem modyfikującym zamiast wielu klawiszyInputActions, które łączą klawisz modyfikujący (np. użyj Shift i W, A, S, D zamiast Shift + W, Shift + A, Shift + S, Shift + D). - Zmiana mapowania danych wejściowych jest automatycznie wyłączana, gdy użytkownik wpisuje tekst w polach tekstowych. Aby mieć pewność, że Android może wykrywać pola tekstowe w Twojej grze i zapobiegać zakłócaniu ich działania przez ponownie zmapowane klawisze, postępuj zgodnie ze sprawdzonymi metodami wdrażania pól tekstowych na Androidzie. Jeśli Twoja gra musi używać nietypowych pól tekstowych, możesz ręcznie wyłączyć ponowne mapowanie za pomocą
setInputContext()zInputContextzawierającym pustą listęInputGroups. - Jeśli gra obsługuje ponowne mapowanie, rozważ zaktualizowanie przypisań klawiszy. Jest to operacja wrażliwa, która może powodować konflikty z wersjami zapisanymi przez użytkownika. W miarę możliwości unikaj zmiany identyfikatorów istniejących elementów sterujących.
Funkcja ponownego mapowania
Gry Google Play na PC obsługują zmianę przypisań klawiszy na podstawie powiązań klawiszy, które Twoja gra udostępnia za pomocą pakietu Input SDK. Jest to opcjonalne i można to całkowicie wyłączyć. Możesz na przykład udostępnić własny interfejs do zmiany mapowania klawiatury. Aby wyłączyć ponowne mapowanie w grze, wystarczy określić, że opcja ponownego mapowania jest wyłączona dla InputMap (więcej informacji znajdziesz w artykule Tworzenie InputMap).
Aby uzyskać dostęp do tej funkcji, użytkownicy muszą otworzyć nakładkę, a następnie kliknąć działanie, które chcą zmienić. Po każdym zdarzeniu ponownego mapowania Gry Google Play na PC mapują każdy ponownie zmapowany przez użytkownika element sterujący na domyślne elementy sterujące, których oczekuje Twoja gra, więc nie musi ona wiedzieć o ponownym mapowaniu przez gracza. Opcjonalnie możesz zaktualizować komponenty używane do wyświetlania elementów sterujących klawiaturą w grze, dodając wywołanie zwrotne do ponownego mapowania zdarzeń.

Gry Google Play na PC przechowują lokalnie zmienione ustawienia sterowania dla każdego użytkownika, dzięki czemu są one zachowywane podczas kolejnych sesji grania. Te informacje są przechowywane na dysku tylko na platformie PC i nie mają wpływu na korzystanie z urządzeń mobilnych. Dane kontrolne są usuwane, gdy użytkownik odinstaluje lub ponownie zainstaluje Gry Google Play na PC. Te dane nie są trwałe na wielu komputerach.
Aby obsługiwać funkcję ponownego mapowania w swojej grze, unikaj tych ograniczeń:
Ograniczenia ponownego mapowania
Funkcje zmiany przypisania klawiszy można wyłączyć w grze, jeśli przypisania klawiszy zawierają którykolwiek z tych przypadków:
- Skróty wieloklawiszowe
InputActions, które nie składają się z klawisza modyfikującego i klawisza niemodyfikującego. Na przykład Shift + A jest prawidłowy, ale A + B, Ctrl + Alt lub Shift + A + Tab nie są. InputMapzawieraInputActions,InputGroupslubInputContextsz powtórzonymi unikalnymi identyfikatorami.
Ograniczenia ponownego mapowania
Podczas projektowania przypisań klawiszy do ponownego mapowania weź pod uwagę te ograniczenia:
- Zmiana przypisania na kombinacje klawiszy nie jest obsługiwana. Użytkownicy nie mogą na przykład zmienić przypisania Shift + A na Ctrl + B ani A na Shift + A.
- Zmiana mapowania nie jest obsługiwana w przypadku
InputActionsz przyciskami myszy. Na przykład Shift + prawy przycisk myszy nie można ponownie przypisać.
Testowanie ponownego mapowania klawiszy w emulatorze Gier Google Play na PC
Funkcję ponownego mapowania możesz włączyć w dowolnym momencie w emulatorze Gier Google Play na PC, wydając to polecenie adb:
adb shell dumpsys input_mapping_service --set RemappingFlagValue true
Nakładka zmieni się tak jak na tym obrazie:

Dodawanie pakietu SDK
Zainstaluj pakiet Input SDK zgodnie z platformą programowania.
Java i Kotlin
Pobierz Input SDK dla języka Java lub Kotlin, dodając zależność do pliku build.gradle na poziomie modułu:
dependencies {
implementation 'com.google.android.libraries.play.games:inputmapping:1.1.1-beta'
...
}
Unity
Pakiet Input SDK to standardowy pakiet Unity z kilkoma zależnościami.
Wymagana jest instalacja pakietu ze wszystkimi zależnościami. Pakiety można zainstalować na kilka sposobów.
Zainstaluj .unitypackage
Pobierz plik unitypackage pakietu SDK Input wraz ze wszystkimi zależnościami. Możesz zainstalować .unitypackage, wybierając Assets > Import package > Custom Package i znajdując pobrany plik.
Instalowanie za pomocą UPM
Możesz też zainstalować pakiet za pomocą menedżera pakietów Unity, pobierając plik .tgz i instalując jego zależności:
- 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.libraries.play.games.inputmapping-1.1.1-beta (lub wybierając plik tgz z tego archiwum)
Instalowanie za pomocą OpenUPM
Pakiet możesz zainstalować za pomocą OpenUPM.
$ openupm add com.google.android.libraries.play.games.inputmapping
Przykładowe gry
Przykłady integracji z pakietem Input SDK znajdziesz w AGDK Tunnel w przypadku gier w Kotlinie lub Javie oraz w Trivial Kart w przypadku gier w Unity.
Generowanie powiązań klawiszy
Zarejestruj powiązania klawiszy, tworząc InputMap i zwracając go za pomocą InputMappingProvider. Poniższy przykład przedstawia 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
Określ działania wejściowe
Klasa InputAction służy do mapowania klucza lub kombinacji klawiszy na działanie w grze. InputActions musi mieć unikalne identyfikatory we wszystkich klasach InputActions.
Jeśli obsługujesz zmianę mapowania, możesz określić, co można zmienić. Jeśli Twoja gra nie obsługuje zmiany mapowania, wyłącz tę opcję dla wszystkich InputActions. Pakiet Input SDK jest jednak wystarczająco inteligentny, aby wyłączyć zmianę mapowania, jeśli nie jest ona obsługiwana w InputMap.InputActions
W tym przykładzie klawisz
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 );

Działania mogą też reprezentować dane wejściowe z myszy. W tym przykładzie kliknięcie lewym przyciskiem jest ustawione na działanie Przenieś:
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 );

Kombinacje klawiszy są określane przez przekazywanie wielu kodów klawiszy do elementu
InputAction. W tym przykładzie
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 );

Pakiet SDK Input umożliwia łączenie przycisków myszy i klawiatury w jednym działaniu. Ten przykład pokazuje, że naciśnięcie jednocześnie klawisza
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 );

Obiekt InputAction ma te pola:
ActionLabel: ciąg znaków wyświetlany w interfejsie, który reprezentuje to działanie. Lokalizacja nie jest wykonywana automatycznie, więc przeprowadź ją z wyprzedzeniem.InputControls: określa elementy sterujące, których używa to działanie. Elementy sterujące są mapowane na spójne symbole w nakładce.InputActionId: obiektInputIdentifier, który przechowuje identyfikator numeru i wersjęInputAction(więcej informacji znajdziesz w sekcji Identyfikatory kluczy śledzenia).InputRemappingOption: jedna z wartościInputEnums.REMAP_OPTION_ENABLEDlubInputEnums.REMAP_OPTION_DISABLED. Określa, czy działanie można ponownie przypisać. Jeśli gra nie obsługuje ponownego przypisywania, możesz pominąć to pole lub po prostu ustawić je jako wyłączone.RemappedInputControls: obiektInputControlstylko do odczytu, który służy do odczytywania zestawu kluczy zmapowanego przez użytkownika podczas zdarzeń ponownego mapowania (używany do otrzymywania powiadomień o zdarzeniach ponownego mapowania).
InputControls reprezentuje dane wejściowe powiązane z działaniem i zawiera te pola:
AndroidKeycodes: to lista liczb całkowitych reprezentujących dane wejściowe z klawiatury powiązane z działaniem. Są one zdefiniowane w klasie KeyEvent lub w klasie AndroidKeycode w przypadku Unity.MouseActions: to lista wartościMouseActionreprezentujących dane wejściowe myszy powiązane z tym działaniem.
Zdefiniuj grupy wejściowe
InputActions są grupowane z powiązanymi logicznie działaniami za pomocą InputGroups, aby ułatwić nawigację i odkrywanie elementów sterujących w nakładce. Każdy identyfikator musi być unikalny w przypadku wszystkich InputGroups w Twojej grze.InputGroup
Grupowanie działań wejściowych ułatwia graczowi znalezienie odpowiedniego przypisania klawiszy w bieżącym kontekście.
Jeśli obsługujesz zmianę mapowania, możesz określić, co można zmienić. Jeśli Twoja gra nie obsługuje zmiany mapowania, wyłącz tę opcję dla wszystkich InputGroups. Pakiet Input SDK jest jednak wystarczająco inteligentny, aby wyłączyć zmianę mapowania, jeśli nie jest ona obsługiwana w InputMap.InputGroups
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 );
Poniższy przykład przedstawia grupy wejściowe Elementy sterujące drogą i Elementy sterujące menu w nakładce:

InputGroup zawiera te pola:
GroupLabel: ciąg znaków, który ma być wyświetlany w nakładce i może służyć do logicznego grupowania zestawu działań. Ten ciąg znaków nie jest automatycznie lokalizowany.InputActions: lista obiektówInputActionzdefiniowanych w poprzednim kroku. Wszystkie te działania są wyświetlane wizualnie pod nagłówkiem grupy.InputGroupId: obiektInputIdentifier, który przechowuje identyfikator liczbowy i wersjęInputGroup. Więcej informacji znajdziesz w sekcji Identyfikatory kluczy śledzenia.InputRemappingOption: jedna z wartościInputEnums.REMAP_OPTION_ENABLEDlubInputEnums.REMAP_OPTION_DISABLED. Jeśli ta opcja jest wyłączona, wszystkie obiektyInputActionnależące do tej grupy będą miały wyłączone ponowne mapowanie, nawet jeśli określają, że opcja ponownego mapowania jest włączona. Jeśli ta opcja jest włączona, wszystkie działania należące do tej grupy można ponownie mapować, chyba że poszczególne działania określają, że ponowne mapowanie jest wyłączone.
Określanie kontekstów wejściowych
InputContexts umożliwia grze używanie różnych zestawów elementów sterujących klawiatury w różnych scenach. Przykład:
- Możesz określić różne zestawy danych wejściowych do poruszania się po menu i do poruszania się w grze.
- Możesz określić różne zestawy danych wejściowych w zależności od sposobu poruszania się w grze, np. jazdy samochodem lub chodzenia.
- Możesz określić różne zestawy danych wejściowych w zależności od bieżącego stanu gry, np. podczas poruszania się po świecie gry lub podczas rozgrywania poszczególnych poziomów.
Gdy używasz InputContexts, nakładka wyświetla najpierw grupy kontekstu w użyciu. Aby włączyć to działanie, wywołaj funkcję setInputContext(), aby ustawić kontekst za każdym razem, gdy gra przechodzi do innej sceny. Ilustruje to poniższy obraz: w scenie „prowadzenie pojazdu” elementy sterujące drogą są wyświetlane u góry nakładki. Po otwarciu menu „Sklep” u góry nakładki wyświetlają się działania „Elementy sterujące menu”.

Aktualizacje nakładki są realizowane przez ustawienie innego parametru InputContext w różnych momentach gry. Aby to zrobić:
- Grupuj
InputActionsz logicznie powiązanymi działaniami za pomocąInputGroups - Przypisz te
InputGroupsdoInputContextw różnych częściach gry.
InputGroups należące do tego samegoInputContextnie mogą mieć sprzecznychInputActions, w których używany jest ten sam klucz. Dobrze jest przypisać każdy InputGroup do jednego InputContext.
Poniższy przykładowy kod pokazuje logikę InputContext:
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 zawiera te pola:
LocalizedContextLabel: ciąg znaków opisujący grupy należące do kontekstu.InputContextId: obiektInputIdentifier, który przechowuje identyfikator numeru i wersjęInputContext(więcej informacji znajdziesz w sekcji Identyfikatory kluczy śledzenia).ActiveGroups: listaInputGroups, które mają być używane i wyświetlane u góry nakładki, gdy ten kontekst jest aktywny.
Tworzenie mapy wejścia
InputMap to zbiór wszystkich obiektów InputGroup dostępnych w grze, a tym samym wszystkich obiektów InputAction, z którymi gracz może wejść w interakcję.
Podczas zgłaszania przypisań klawiszy tworzysz InputMap ze wszystkimi InputGroups używanymi w grze.
Jeśli gra nie obsługuje zmiany mapowania, wyłącz tę opcję i usuń zarezerwowane klawisze.
W tym przykładzie tworzymy InputMap, który służy do raportowania kolekcji 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 zawiera te pola:
InputGroups: grupy wejściowe zgłoszone przez grę. Grupy są wyświetlane w kolejności w nakładce, chyba że określono bieżące grupy w użyciu, wywołującsetInputContext().MouseSettings: obiektMouseSettingswskazuje, że czułość myszy można dostosować i że mysz jest odwrócona na osi Y.InputMapId:InputIdentifierobiekt, który przechowuje identyfikator liczbowy i wersjęInputMap(więcej informacji znajdziesz w sekcji Identyfikatory kluczy śledzenia).InputRemappingOption: jedna z wartościInputEnums.REMAP_OPTION_ENABLEDlubInputEnums.REMAP_OPTION_DISABLED. Określa, czy funkcja ponownego mapowania jest włączona.ReservedControls: listaInputControls, których użytkownicy nie będą mogli ponownie przypisać.
Śledzenie identyfikatorów kluczy
Obiekty InputAction, InputGroup, InputContext i InputMap zawierają obiekt InputIdentifier, który przechowuje unikalny identyfikator liczbowy i identyfikator wersji w postaci ciągu znaków. Śledzenie wersji obiektów w postaci ciągu znaków jest opcjonalne, ale zalecane w przypadku śledzenia wersji obiektów InputMap. Jeśli wersja w postaci ciągu znaków nie zostanie podana, ciąg znaków będzie pusty. Wersja w postaci ciągu znaków jest wymagana w przypadku obiektów InputMap.
W przykładzie poniżej przypisujemy wersję ciągu znaków do InputActions lub 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
Identyfikatory obiektów InputAction muszą być unikalne we wszystkich InputActions w InputMap. Podobnie identyfikatory obiektów InputGroup muszą być unikalne we wszystkich InputGroups w InputMap. Poniższy przykład pokazuje, jak używać enum do śledzenia unikalnych identyfikatorów obiektów:
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 zawiera te pola:
UniqueId: unikalny identyfikator liczbowy ustawiony w celu jednoznacznego zidentyfikowania danego zbioru danych wejściowych.VersionString: ciąg znaków czytelny dla człowieka, który służy do identyfikowania wersji danych wejściowych między 2 wersjami zmian danych wejściowych.
Otrzymywanie powiadomień o zdarzeniach ponownego mapowania (opcjonalnie)
Otrzymuj powiadomienia o zdarzeniach ponownego przypisania, aby wiedzieć, które klawisze są używane w Twojej grze. Dzięki temu gra może aktualizować elementy wyświetlane na ekranie, które służą do wyświetlania elementów sterujących.
Na ilustracji poniżej widać przykład takiego działania. Po ponownym przypisaniu klawiszy

Aby to zrobić, zarejestruj wywołanie zwrotne InputRemappingListener. Aby wdrożyć tę funkcję, zacznij od zarejestrowania instancji InputRemappingListener:
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 otrzymuje powiadomienie w momencie uruchomienia po wczytaniu zapisanych przez użytkownika zmienionych ustawień sterowania oraz za każdym razem, gdy użytkownik zmieni przypisanie klawiszy.
Inicjowanie
Jeśli używasz InputContexts, ustawiaj kontekst przy każdym przejściu do nowej sceny, w tym pierwszy kontekst używany w początkowej scenie. Musisz ustawić InputContext po zarejestrowaniu InputMap.
Jeśli używasz InputRemappingListeners, aby otrzymywać powiadomienia o zdarzeniach ponownego mapowania, zarejestruj InputRemappingListener przed zarejestrowaniem InputMappingProvider. W przeciwnym razie Twoja gra może przegapić ważne zdarzenia w momencie uruchomienia.
Poniższy przykład pokazuje, jak zainicjować interfejs API:
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 } }
Czyszczenie danych
Wyrejestruj instancję InputMappingProvider i wszystkie instancje InputRemappingListener po zamknięciu gry, chociaż pakiet Input SDK jest wystarczająco inteligentny, aby uniknąć wycieku zasobów, nawet jeśli tego nie zrobisz:
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
Implementację pakietu Input SDK możesz przetestować, ręcznie otwierając nakładkę, aby zobaczyć, jak wygląda odtwarzacz, lub za pomocą powłoki adb, aby przeprowadzić automatyczne testowanie i weryfikację.
Emulator Gier Google Play na PC sprawdza poprawność mapy wejść pod kątem typowych błędów. W przypadku scenariuszy takich jak zduplikowane unikalne identyfikatory, używanie różnych map wejściowych lub niepowodzenie reguł ponownego mapowania (jeśli ponowne mapowanie jest włączone) nakładka wyświetla komunikat o błędzie, jak poniżej:

Sprawdź wdrożenie pakietu Input SDK za pomocą polecenia adb w wierszu poleceń.
Aby uzyskać bieżącą mapę wejść, użyj tego polecenia adb shell (zastąp MY.PACKAGE.NAME nazwą gry):
adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME
Jeśli rejestracja InputMap się powiedzie, zobaczysz dane wyjściowe podobne do tych:
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
}
Lokalizacja
Pakiet SDK do wprowadzania danych nie korzysta z systemu lokalizacji Androida. W związku z tym podczas przesyłania InputMap musisz podać zlokalizowane ciągi znaków. Możesz też użyć systemu lokalizacji silnika gry.
Proguard
Jeśli do minifikacji gry używasz Proguarda, dodaj do pliku konfiguracji Proguarda te reguły, aby pakiet SDK nie został usunięty z pakietu końcowego:
-keep class com.google.android.libraries.play.hpe.** { *; }
-keep class com.google.android.libraries.play.games.inputmapping.** { *; }
Co dalej?
Po zintegrowaniu pakietu SDK do obsługi danych wejściowych z grą możesz spełnić pozostałe wymagania dotyczące Gier Google Play na PC. Więcej informacji znajdziesz w artykule Pierwsze kroki z Grami Google Play na PC.