Ten dokument opisuje, jak skonfigurować i wyświetlić pakiet SDK wejściowych w które obsługują Gry Google Play na PC. Zadania obejmują dodanie pakietu SDK do gry i generując mapę wejściową, która zawiera przypisania działań i danych wejściowych użytkownika w grze.
Zanim rozpoczniesz
Zanim dodasz pakiet SDK wejściowych do gry, musisz obsługiwać wprowadzanie tekstu za pomocą klawiatury i myszy za pomocą silnika gry .
Pakiet SDK wejściowych dostarcza do Gier Google Play na PC informacje o tym, które elementy sterujące grą są używane, aby można je było wyświetlić użytkownikowi. Może też opcjonalnie zezwolić użytkownikom na ponowne przypisywanie klawiatury.
Każdy element sterujący to InputAction
(np. „J” zamiast „Jump”) i porządkujesz
InputActions
do InputGroups
. Element InputGroup
może reprezentować inny
tryb gry, np. „Jazda samochodem”. lub „Pieszo” lub „Menu główne”. Możesz też
użyj parametru InputContexts
, aby wskazać, które grupy są aktywne w różnych punktach
w całej grze.
Możesz włączyć automatyczne oznaczanie klawiatury, ale jeśli wolisz mieć własny interfejs ponownego mapowania elementów sterujących, możesz go wyłączyć Ponowne mapowanie wejściowe pakietu SDK.
Poniższy diagram sekwencji opisuje sposób działania interfejsu API pakietu SDK danych wejściowych:
Gdy gra korzysta z pakietu SDK wejścia, widoczne są elementy sterujące w nakładce Gry Google Play na PC.
Nakładka Gry Google Play na PC
Nakładka Gry Google Play na PC („nakładka”) z elementami sterującymi które uwzględnia gra. Użytkownicy mogą w każdej chwili przejść do nakładki: naciskając Shift + Tab.
Sprawdzone metody projektowania powiązań kluczy
Podczas projektowania powiązań kluczy kieruj się tymi sprawdzonymi metodami:
- Aby ulepszyć działanie usługi, pogrupuj
InputActions
w logicznie powiązaneInputGroups
nawigacji i wykrywalności elementów sterujących podczas rozgrywki. - Przypisz każde
InputGroup
do maksymalnie jednego elementuInputContext
. DrobnoziarnistyInputMap
ułatwia poruszanie się po elementach sterujących aby wyświetlić nakładkę. - Utwórz
InputContext
dla każdego rodzaju sceny w grze. Zwykle możesz użyć jednegoInputContext
do wszystkich elementów menu podobnych do tych w menu. wiele scen. Używaj różnychInputContexts
do wszystkich minigier w grze lub alternatywnych elementów sterujących pojedynczej sceny. - Jeśli 2 działania są zaprojektowane tak, aby korzystały z tego samego klucza w ramach tego samego klucza
InputContext
, użyj ciągu etykiety, np. „Interakcja / ogień”. - Jeśli 2 klucze mają służyć do powiązania z tym samym elementem
InputAction
, użyj 2 różneInputActions
, które wykonują to samo działanie w Twojej grze. Możesz użyć tego samego ciągu etykiety w przypadku obu właściwościInputActions
, ale jego identyfikator musi być ciągiem w inny sposób. - Jeśli do zestawu kluczy jest stosowany klawisz modyfikujący, należy rozważyć używanie jednego
InputAction
klawiszem modyfikującym, a nie z kilkoma argumentamiInputActions
, połącz klawisz modyfikujący (np. użyj Shift oraz W, A, S, D Shift + W, Shift + A, Shift + S, Shift + D). - Ponowne mapowanie danych wejściowych jest wyłączane automatycznie, gdy użytkownik pisze tekst
. Postępuj zgodnie ze sprawdzonymi metodami implementacji pól tekstowych Androida, aby mieć pewność,
aby Android mógł wykrywać pola tekstowe w grze i zapobiegać zmapowaniu klawiszy
ingerencji w te prawa. Jeśli gra musi korzystać z niekonwencjonowanego tekstu
możesz użyć pola
setInputContext()
z parametremInputContext
zawierającym pusta lista wartościInputGroups
, aby ręcznie wyłączyć ponowne mapowanie. - Jeśli Twoja gra obsługuje ponowne mapowanie, rozważ zaktualizowanie powiązań klawiszy poufna operacja, która może kolidować z wersjami zapisanymi przez użytkownika. Unikaj zmienianie identyfikatorów istniejących elementów sterujących w miarę możliwości.
Funkcja ponownego mapowania
Gry Google Play na PC obsługują przemapowywanie sterowania za pomocą klawiatury na podstawie klawisza
powiązaniach dostarczanych przez grę za pomocą pakietu danych wejściowych. To opcjonalne, a
można całkowicie wyłączyć. Na przykład możesz mieć własną klawiaturę
mapowania interfejsu. Aby wyłączyć ponowne mapowanie gier, musisz określić, jak
opcja ponownego mapowania jest wyłączona dla urządzenia InputMap
(zobacz
Utwórz mapę wejściową, aby dowiedzieć się więcej).
Aby uzyskać dostęp do tej funkcji, użytkownik musi otworzyć nakładkę, a potem kliknąć działanie. chcą zmienić mapowanie. Po każdym wydarzeniu z Gier Google Play na PC przypisane przez użytkownika elementy sterujące do domyślnych ustawień, więc gra nie musi pamiętać o mapowaniu graczy. Ty może opcjonalnie aktualizować zasoby używane do wyświetlania elementów sterujących gry przez dodanie wywołania zwrotnego dla ponownego mapowania zdarzeń.
Gry Google Play na PC zapisują elementy sterujące lokalnie dla każdego użytkownika. co daje możliwość zachowania kontroli w sesjach gier. Te informacje są przechowywane tylko na dysku komputera i nie ma wpływu na korzystanie z wersji na urządzenia mobilne. Dane kontrolne są usuwane po odinstalowaniu lub ponownym zainstalowaniu Gier Google Play na PC. Te dane nie są trwałe na wielu urządzeniach PC.
Aby korzystać z funkcji ponownego mapowania w grze, unikaj tych ograniczeń:
Ograniczenia ponownego mapowania
Funkcje ponownego mapowania mogą zostać wyłączone w grze, jeśli powiązania klawiszy zawierają jakiekolwiek za:
- Wiele kluczy
InputActions
, które nie składają się z klawisza modyfikującego + A bez klawisza modyfikującego. Na przykład Shift + A jest prawidłowy, ale A + B, Ctrl + Alt lub Shift + A + Tab – nie. InputMap
zawieraInputActions
,InputGroups
lubInputContexts
z powtarzającymi się unikalnymi identyfikatorami.
Ograniczenia ponownego mapowania
Podczas projektowania wiązań klawiszy pod kątem ponownego mapowania weź pod uwagę te kwestie Ograniczenia:
- Mapowanie do kombinacji klawiszy nie jest obsługiwane. Użytkownicy nie mogą na przykład: zmapuj klawisze Shift + A na Ctrl + B lub A na Shift + A.
- Ponowne mapowanie przy użyciu przycisków myszy nie jest obsługiwane w przypadku elementu
InputActions
. Dla: Na przykład nie można ponownie zmapować klawisza Shift + prawym przyciskiem myszy.
Przetestuj ponowne mapowanie klawiszy w emulatorze Gier Google Play na PC
Funkcję ponownego mapowania w Emulatorze Gier Google Play na PC możesz włączyć w każdej chwili W tym celu uruchom to polecenie adb:
adb shell dumpsys input_mapping_service --set RemappingFlagValue true
Nakładka zmieni się jak na obrazie poniżej:
Dodaj pakiet SDK
Zainstaluj pakiet SDK wejściowych zgodnie ze swoją platformą deweloperską.
Java i Kotlin
Pobierz pakiet SDK wejściowych dla języka Java lub Kotlin, dodając zależność do
plik build.gradle
na poziomie modułu:
dependencies {
implementation 'com.google.android.libraries.play.games:inputmapping:1.1.0-beta'
...
}
Jedność
Pakiet SDK danych wejściowych to standardowy pakiet Unity z kilkoma zależnościami.
Wymagane jest zainstalowanie pakietu ze wszystkimi zależnościami. Jest kilka sposobów , aby zainstalować pakiety.
Zainstaluj aplikację .unitypackage
Pobierz plik pakietu jednostkowego pakietu SDK wejściowego
ze wszystkimi zależnościami. Możesz zainstalować aplikację .unitypackage
, wybierając
Zasoby > Importuj pakiet > Niestandardowy pakiet i lokalizowanie pobranego pliku.
Instalowanie za pomocą UPM
Możesz też zainstalować pakiet za pomocą
Unity's Package Manager (Menedżer pakietów Unity)
Pobieram .tgz
i instaluję 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.0-beta
Zainstaluj 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 SDK wejściowych: Tunel AGDK dla gier Kotlin i Javy oraz Gokarta trygonometryczna w grach Unity.
Wygeneruj powiązania kluczy
Zarejestruj powiązania kluczy, tworząc obiekt InputMap
i zwracając go za pomocą
InputMappingProvider
W poniższym przykładzie
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
Zdefiniuj działania wejściowe
Klasa InputAction
służy do mapowania klucza lub kombinacji klawiszy na grę.
działania. InputActions
musi mieć unikalne identyfikatory w całym elemencie InputActions
.
Jeśli wspierasz ponowne mapowanie, możesz określić, czym może być obiekt InputActions
przeniesione. Jeśli Twoja gra nie obsługuje ponownego mapowania, musisz je ustawić.
wyłączono opcję dla wszystkich Twoich InputActions
, ale pakiet SDK wejścia jest
na tyle inteligentnych, aby wyłączyć ponowne mapowanie, jeśli nie jest obsługiwane
InputMap
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 myszki. W tym przykładzie opcja Kliknięcie lewym przyciskiem myszy ustawiana jest na wartość 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 przekazanie wielu kodów klawiszy na klucz
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 danych wejściowych zawiera pakiet SDK do wprowadzania danych, który pozwala łączyć jednocześnie przyciski myszy i klawiszy
jedno działanie. Ten przykład wskazuje, że klawisze
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 );
Dane wejściowe działania mają te pola:
ActionLabel
: ciąg znaków wyświetlany w interfejsie oznaczający to działanie. Lokalizacja nie jest wykonywana automatycznie, więc ją tłumacz z przodu.InputControls
: określa elementy sterujące danymi wejściowymi używane przez to działanie. elementy sterujące mapą na spójne glify w nakładce.InputActionId
: obiektInputIdentifier
, który przechowuje identyfikator i wersję numeruInputAction
(zobacz identyfikatory kluczy śledzenia, aby dowiedzieć się więcej) ).InputRemappingOption
: jedna zInputEnums.REMAP_OPTION_ENABLED
lubInputEnums.REMAP_OPTION_DISABLED
Określa, czy działanie jest włączone ich mapowanie. Jeśli Twoja gra nie obsługuje ponownego mapowania, możesz pominąć to pole lub po prostu wyłączyć tę funkcję.RemappedInputControls
: tylko do odczytu obiektInputControls
używany do odczytu przemapowany klawisz ustawiony przez użytkownika przy mapowaniu zdarzeń (używane w przypadku otrzymywać powiadomienia o remapowaniu zdarzeń).
InputControls
reprezentuje dane wejściowe powiązane z działaniem i zawiera
tych pól:
AndroidKeycodes
: to lista liczb całkowitych reprezentujących dane wejściowe z klawiatury powiązane z działaniem. Są one zdefiniowane w Kluczowe zdarzenie lub AndroidKeycode dla Unity.MouseActions
: to lista wartościMouseAction
reprezentujących dane wejściowe myszy powiązane z tym działaniem.
Zdefiniuj grupy danych wejściowych
InputActions
są zgrupowane z działaniami powiązanymi logicznie za pomocą argumentu InputGroups
do
poprawić nawigację i wykrywalność elementów sterujących w nakładce. Każdy
Identyfikator InputGroup
musi być unikalny wśród wszystkich elementów (InputGroups
) w Twojej grze.
Łącząc działania wejściowe w grupy, ułatwiasz graczowi aby znaleźć prawidłowe powiązanie klucza dla bieżącego kontekstu.
Jeśli wspierasz ponowne mapowanie, możesz określić, czym może być obiekt InputGroups
przeniesione. Jeśli Twoja gra nie obsługuje ponownego mapowania, musisz je ustawić.
wyłączono opcję dla wszystkich Twoich InputGroups
, ale pakiet SDK wejścia jest
na tyle inteligentnych, aby wyłączyć ponowne mapowanie, jeśli nie jest obsługiwane
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 );
W przykładzie poniżej widać Elementy sterujące drogi i Elementy sterujące menu grupy wejściowe w nakładce:
InputGroup
zawiera te pola:
GroupLabel
: ciąg znaków do wyświetlania w nakładce, którego można użyć, pogrupować logicznie zbiór działań. Ten ciąg nie jest automatycznie i zlokalizowanego.InputActions
: listaInputAction
obiektów zdefiniowanych w poprzedniej sekcji krok po kroku. Wszystkie te działania są wyświetlane wizualnie pod nagłówkiem grupy.InputGroupId
: obiektInputIdentifier
, który przechowuje identyfikator numeru i wersjiInputGroup
. Zobacz Identyfikatory kluczy śledzenia: znajdziesz więcej informacji.InputRemappingOption
: jedna zInputEnums.REMAP_OPTION_ENABLED
lubInputEnums.REMAP_OPTION_DISABLED
Jeśli zasada jest wyłączona, wszystkieInputAction
obiekty należące do tej grupy będą wyłączone ponownie, nawet jeśli włącz opcję ponownego mapowania. Jeśli ta opcja jest włączona, wszystkie działania należące do do tej grupy można przypisać ponownie, chyba że zostanie wyłączona przez osobę .
Zdefiniuj konteksty danych wejściowych
W funkcji InputContexts
gra może używać innego zestawu sterowania za pomocą klawiatury
różne sceny gry. Na przykład:
- Możesz określić różne zestawy danych wejściowych do poruszania się po menu i inne dane wejściowe do poruszania się po menu w danej grze.
- Możesz określić różne zestawy danych wejściowych w zależności od trybu ruchu. takich jak jazda samochodem czy chodzenie.
- Możesz określić różne zestawy danych wejściowych w zależności od bieżącego stanu np. poruszanie się po świecie, a nie granie na poziomie indywidualnym.
Gdy używasz interfejsu InputContexts
, nakładka pokazuje najpierw grupy kontekstu
w użyciu. Aby włączyć to zachowanie, wywołaj setInputContext()
w celu ustawienia
za każdym razem, gdy gra wkracza w inną scenę. Następujący obraz
demonstruje takie zachowanie: podczas jazdy elementy sterujące drogą,
działania są wyświetlane w górnej części nakładki. Podczas otwierania „sklepu” ,
„Elementy sterujące menu” działania są wyświetlane w górnej części nakładki.
Te aktualizacje nakładki są osiągane przez ustawienie innego parametru InputContext
na poziomie
w różnych punktach gry. Aby to zrobić:
- Pogrupuj
InputActions
za pomocą logicznie powiązanych działań za pomocą argumentuInputGroups
- Przypisz te elementy (
InputGroups
) do elementuInputContext
obejmującego różne części Twoja gra
InputGroups
należące do tego samego InputContext
nie mogą powodować konfliktów
InputActions
w przypadku tego samego klucza. Dobrze jest przypisać każdej z nich
InputGroup
do pojedynczej kolumny InputContext
.
Poniższy przykładowy kod ilustruje 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 opisujący grupy należące do i dodaje kontekst.InputContextId
: obiektInputIdentifier
, który przechowuje identyfikator i wersję numeruInputContext
(zobacz identyfikatory kluczy śledzenia, aby dowiedzieć się więcej) ).ActiveGroups
: lista wartościInputGroups
, która będzie używana i wyświetlana u góry nakładki, gdy ten kontekst jest aktywny.
Tworzenie mapy wejściowej
Element InputMap
to kolekcja wszystkich obiektów InputGroup
dostępnych w
czyli wszystkie obiekty InputAction
, których gracz może się spodziewać
skuteczność.
Podczas raportowania powiązań kluczy tworzysz InputMap
ze wszystkimi
InputGroups
wykorzystane w grze.
Jeśli Twoja gra nie obsługuje ponownego mapowania, wyłącz opcję ponownego mapowania. zarezerwowane klucze są puste.
Poniższy przykład pozwala utworzyć obiekt InputMap
używany 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łaszane przez grę. Te grupy są wyświetlane w nakładce w kolejności, o ile nie określono bieżących grup w użyj połączeniasetInputContext()
.MouseSettings
: obiektMouseSettings
wskazuje czułość myszy. może zostać odwrócona, a mysz znajduje się na osi Y.InputMapId
: obiektInputIdentifier
, który przechowuje identyfikator numeru i wersjęInputMap
(zobacz identyfikatory kluczy śledzenia, ).InputRemappingOption
: jedna zInputEnums.REMAP_OPTION_ENABLED
lubInputEnums.REMAP_OPTION_DISABLED
Określa, czy funkcja ponownego mapowania jest .ReservedControls
: lista elementówInputControls
, których użytkownicy nie będą mogli robić i zmapować je.
Identyfikatory kluczy śledzenia
Obiekty InputAction
, InputGroup
, InputContext
i InputMap
zawierają
Obiekt InputIdentifier
, który przechowuje unikalny identyfikator numeru i identyfikator wersji ciągu.
Śledzenie wersji w postaci ciągów znaków jest opcjonalne, ale zalecane, aby można było śledzić
wersje systemu InputMap
. Jeśli nie podano wersji ciągu znaków,
ciąg jest pusty. W przypadku obiektów InputMap
wymagana jest wersja ciągu znaków.
W tym przykładzie 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 numerów obiektów InputAction
muszą być unikalne wśród wszystkich InputActions
w
InputMap
. Podobnie identyfikatory obiektów InputGroup
muszą być unikalne wśród wszystkich
InputGroups
w: InputMap
. Poniższy przykład pokazuje, jak korzystać z
enum
, aby śledzić unikalne identyfikatory obiektu:
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 numeru ustawiony, aby jednoznacznie identyfikować określony zbiór danych wejściowych. danych w unikalny sposób.VersionString
: zrozumiały dla człowieka ciąg znaków wersji identyfikujący wersję. danych wejściowych między 2 wersjami danych wejściowych.
Otrzymuj powiadomienia o ponownym mapowaniu zdarzeń (opcjonalnie)
Otrzymuj powiadomienia o zdarzeniach zmiany mapowania, aby otrzymywać informacje o używanych kluczach Twojej gry. Dzięki temu gra może aktualizować zasoby wyświetlane na ekranie gry służy do wyświetlania elementów sterujących działaniami.
Poniższy obraz przedstawia przykład tego działania, w którym po ponownym zmapowaniu
klawisze
Jest to możliwe przez zarejestrowanie InputRemappingListener
oddzwanianie. Aby wdrożyć to rozwiązanie, zacznij od zarejestrowania
Instancja 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
Aplikacja InputRemappingListener
zostanie powiadomiona w momencie uruchomienia po wczytaniu
zapisanych przez użytkownika elementów sterujących i za każdym razem, gdy użytkownik ponownie przyporządkuje klawisze.
Inicjalizacja
Jeśli używasz InputContexts
, ustaw kontekst dla każdego
przejście do nowej sceny, łącznie z pierwszym kontekstem użytym na początku
scena. InputContext
musisz ustawić po zarejestrowaniu
InputMap
Jeśli używasz usługi InputRemappingListeners
do otrzymywania powiadomień o ponownym mapowaniu zdarzeń
zarejestruj: InputRemappingListener
, zanim zarejestrujesz
InputMappingProvider
, w przeciwnym razie gra może przegapić ważne wydarzenia w czasie
czasu 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 } }
Uporządkuj
Wyrejestruj instancję InputMappingProvider
i wszystkie instancje InputRemappingListener
gdy gra jest zamknięta, mimo że pakiet SDK wejścia jest inteligentny
aby uniknąć wycieku zasobów, jeśli:
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
Możesz przetestować implementację pakietu SDK wejściowego, ręcznie otwierając nakładkę, aby wyświetlić działanie odtwarzacza, lub za pomocą powłoki adb. do automatycznego testowania i weryfikacji.
Emulator Gier Google Play na PC sprawdza poprawność mapy wejściowej
z typowymi błędami. W przypadku powielonych unikalnych identyfikatorów przy użyciu różnych
lub nieprawidłowe reguły mapowania (jeśli jest włączone ponowne mapowanie),
wyświetla się następujący komunikat o błędzie:
Sprawdź implementację pakietu SDK wejściowego, używając narzędzia adb
w wierszu poleceń.
Aby pobrać bieżącą mapę wejściową, użyj tego polecenia adb shell
(zastąp
MY.PACKAGE.NAME
nazwą swojej gry):
adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME
W przypadku pomyślnego zarejestrowania domeny wyświetli się wynik podobny do tego.
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
}
Lokalizacja
Pakiet SDK danych wejściowych nie używa systemu lokalizacji Androida. Jako
musisz podać zlokalizowane ciągi tekstowe, gdy przesyłasz pole InputMap
. Ty
może też używać systemu lokalizacji silnika gry.
ProGuard
Jeśli używasz ProGuard do minifikacji gry, dodaj do swojego przed usunięciem pakietu SDK. końcowy pakiet:
-keep class com.google.android.libraries.play.hpe.** { *; }
-keep class com.google.android.libraries.play.games.inputmapping.** { *; }
Co dalej
Możesz kontynuować, gdy zintegrujesz pakiet SDK wejściowych z grą z pozostałymi wymaganiami dotyczącymi Gier Google Play na PC. Aby dowiedzieć się więcej, Więcej informacji znajdziesz w artykule Pierwsze kroki z Grami Google Play na PC.