Bu dokümanda, PC'de Google Play Games'i destekleyen oyunlarda Giriş SDK'sının nasıl ayarlanacağı ve gösterileceği açıklanmaktadır. Bu görevler arasında SDK'yı oyununuza ekleme ve oyundaki işlemlerle kullanıcı girişi arasındaki atamaları içeren bir giriş haritası oluşturma yer alır.
Başlamadan önce
Giriş SDK'sını oyununuza eklemeden önce oyun motorunuzun giriş sistemini kullanarak klavye ve fare girişini desteklemeniz gerekir.
Giriş SDK'sı, oyununuzda kullanılan kontroller hakkında PC Üzerinde Google Play Games'e bilgi sağlar. Böylece bu kontroller kullanıcıya gösterilebilir. Ayrıca, kullanıcıların klavyelerini isteğe bağlı olarak yeniden eşlemelerine de izin verebilir.
Her kontrol bir InputAction
'tir (ör. "Atla" için "J") ve InputActions
'lerinizi InputGroups
olarak düzenlersiniz. InputGroup
, oyununuzdaki farklı bir modu (ör. "Araç kullanma", "Yürüyüş" veya "Ana Menü") temsil edebilir. Oyunun farklı noktalarında hangi grupların etkin olduğunu belirtmek için InputContexts
simgesini de kullanabilirsiniz.
Klavye yeniden eşlemenin sizin için otomatik olarak yapılmasını etkinleştirebilirsiniz. Ancak kendi kontrol yeniden eşleme arayüzünüzü sunmayı tercih ederseniz Giriş SDK'sı yeniden eşlemeyi devre dışı bırakabilirsiniz.
Aşağıdaki ardışık düzen şemasında, Giriş SDK'sının API'sinin işleyiş şekli açıklanmaktadır:
Oyununuz Giriş SDK'sını uyguladığında kontrolleriniz PC Üzerinde Google Play Games yer paylaşımında gösterilir.
PC Üzerinde Google Play Games yer paylaşımı
PC Üzerinde Google Play Games yer paylaşımı ("yer paylaşımı"), oyununuz tarafından tanımlanan kontrolleri gösterir. Kullanıcılar Üst Karakter + Sekme tuşlarına basarak istedikleri zaman yer paylaşımına erişebilir.
Tuş bağlamaları tasarlamayla ilgili en iyi uygulamalar
Tuş bağlamalarını tasarlarken aşağıdaki en iyi uygulamaları göz önünde bulundurun:
- Oyun sırasında kontrollerin gezinme ve bulunabilirliğini iyileştirmek için
InputActions
öğelerinizi mantıksal olarak ilişkiliInputGroups
öğelerde gruplandırın. - Her
InputGroup
öğesini en fazla birInputContext
öğesine atayın. İnce taneliInputMap
, yer paylaşımındaki kontrollerinizin arasında gezinme deneyimini iyileştirir. - Oyununuzdaki her farklı sahne türü için bir
InputContext
oluşturun. Genellikle, tüm "menü benzeri" sahneleriniz için tek birInputContext
kullanabilirsiniz. Oyununuzdaki mini oyunlar veya tek bir sahnedeki alternatif kontroller için farklıInputContexts
kullanın. - İki işlem aynı
InputContext
altında aynı anahtarı kullanacak şekilde tasarlandıysa "Etkileşim kur / Tetikle" gibi bir etiket dizesi kullanın. - İki anahtar aynı
InputAction
'ye bağlanacak şekilde tasarlandıysa oyununuzda aynı işlemi gerçekleştiren 2 farklıInputActions
kullanın. Her ikiInputActions
için de aynı etiket dizesini kullanabilirsiniz ancak kimliği farklı olmalıdır. - Bir değiştirici tuşu bir anahtar grubuna uygulanıyorsa değiştirici tuşunu birleştiren birden fazla
InputActions
yerine değiştirici tuşunu içeren tek birInputAction
kullanabilirsiniz (örnek: Üst Karakter + W, Üst Karakter + A, Üst Karakter + S, Üst Karakter + D yerine Üst Karakter ve W, A, S, D tuşlarını kullanın). - Kullanıcı metin alanlarına yazarken giriş yeniden eşleme otomatik olarak devre dışı bırakılır. Android'in oyununuzdaki metin alanlarını algılayabilmesi ve yeniden eşlenen anahtarların bunlara müdahale etmesini önlemek için Android metin alanlarını uygulamayla ilgili en iyi uygulamaları uygulayın. Oyununuzda geleneksel olmayan metin alanları kullanılması gerekiyorsa yeniden eşlemeyi manuel olarak devre dışı bırakmak için
setInputContext()
ile boş birInputGroups
listesi içeren birInputContext
kullanabilirsiniz. - Oyununuz yeniden eşlemeyi destekliyorsa anahtar bağlamalarınızı güncelleyebilirsiniz. Bu hassas işlem, kullanıcı tarafından kaydedilen sürümlerle çakışabilir. Mümkün olduğunda mevcut denetimlerin kimliklerini değiştirmekten kaçının.
Yeniden eşleme özelliği
PC Üzerinde Google Play Games, oyununuzun Giriş SDK'sını kullanarak sağladığı tuş bağlamalarına göre klavye kontrolünün yeniden haritalanmasını destekler. Bu isteğe bağlıdır ve tamamen devre dışı bırakılabilir. Örneğin, kendi klavye yeniden eşleme arayüzünüzü sağlamak isteyebilirsiniz. Oyununuzda yeniden eşlemeyi devre dışı bırakmak için InputMap
için yeniden eşleme seçeneğini devre dışı bırakmanız yeterlidir (daha fazla bilgi için InputMap oluşturma bölümüne bakın).
Bu özelliğe erişmek için kullanıcıların yer paylaşımını açmaları ve ardından yeniden eşlemek istedikleri işlemi tıklamaları gerekir. PC Üzerinde Google Play Games, her yeniden eşleme etkinliğinde kullanıcı tarafından yeniden eşlenen her kontrolü, oyununuzun beklediği varsayılan kontrollerle eşler. Böylece oyununuzun, oyuncunun yeniden eşlemesini bilmesi gerekmez. İsteğe bağlı olarak, yeniden eşleme etkinlikleri için geri arama işlevi ekleyerek oyununuzda klavye kontrollerini görüntülemek için kullanılan öğeleri güncelleyebilirsiniz.
PC Üzerinde Google Play Games, yeniden eşlenen kontrolleri her kullanıcı için yerel olarak depolar. Bu sayede, oyun oturumları boyunca kontrolleri aynı şekilde kullanabilirsiniz. Bu bilgiler yalnızca PC platformu için diskte depolanır ve mobil deneyimi etkilemez. Kontrol verileri, kullanıcı PC'de Google Play Games'i kaldırdığında veya yeniden yüklediğinde silinir. Bu veriler birden fazla PC cihazında kalıcı değildir.
Oyununuzda yeniden eşleme özelliğini desteklemek için aşağıdaki kısıtlamalardan kaçının:
Yeniden eşleme kısıtlamaları
Tuş bağlamaları aşağıdaki durumlardan herhangi birini içeriyorsa oyununuzda yeniden eşleme özellikleri devre dışı bırakılabilir:
- Değiştirici tuş + değiştirici olmayan tuştan oluşmayan çoklu
InputActions
. Örneğin, Üst Karakter + A geçerlidir ancak A + B, Ctrl + Alt veya Üst Karakter + A + Sekme geçerli değildir. InputMap
, yinelenen benzersiz kimliklere sahipInputActions
,InputGroups
veyaInputContexts
içeriyor.
Yeniden eşlemeyle ilgili sınırlamalar
Yeniden eşleme için tuş bağlamalarınızı tasarlarken aşağıdaki sınırlamaları göz önünde bulundurun:
- Tuş kombinasyonlarına yeniden eşleme desteklenmez. Örneğin, kullanıcılar Üst Karakter + A'yı Ctrl + B veya A'yı Üst Karakter + A olarak yeniden eşleyemez.
- Fare düğmeleriyle
InputActions
için yeniden eşleme desteklenmez. Örneğin, Üst karakter + sağ tıklama yeniden eşlenemez.
PC Üzerinde Google Play Games Emülatörü'nde tuş yeniden eşlemeyi test etme
Aşağıdaki adb komutunu uygulayarak PC Üzerinde Google Play Games emülatöründe yeniden eşleme özelliğini istediğiniz zaman etkinleştirebilirsiniz:
adb shell dumpsys input_mapping_service --set RemappingFlagValue true
Yer paylaşımı aşağıdaki resimdeki gibi değiştirildi:
SDK'yı ekleme
Giriş SDK'sını geliştirme platformunuza göre yükleyin.
Java ve Kotlin
Modül düzeyindeki build.gradle
dosyanıza bağımlılık ekleyerek Java veya Kotlin için giriş SDK'sını alın:
dependencies {
implementation 'com.google.android.libraries.play.games:inputmapping:1.1.1-beta'
...
}
Unity
Giriş SDK'sı, çeşitli bağımlılıklara sahip standart bir Unity paketidir.
Paketin tüm bağımlılıklarıyla birlikte yüklenmesi gerekir. Paketleri yüklemenin birkaç yolu vardır.
.unitypackage
Tüm bağımlılıklarıyla birlikte Giriş SDK'sı unitypackage dosyasını indirin. Öğeler > Paketi içe aktar > Özel Paket'i seçip indirdiğiniz dosyayı bularak .unitypackage
'ü yükleyebilirsiniz.
UPM'yi kullanarak yükleme
Alternatif olarak, .tgz
'yi indirip bağımlılarını yükleyerek paketi Unity Package Manager'ı kullanarak da yükleyebilirsiniz:
- 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 (veya bu arşivdeki tgz dosyasını seçin)
OpenUPM'yi kullanarak yükleme
Paketi OpenUPM'i kullanarak yükleyebilirsiniz.
$ openupm add com.google.android.libraries.play.games.inputmapping
Örnek oyunlar
Giriş SDK'sı ile entegrasyon örnekleri için Kotlin veya Java oyunları için AGDK Tunnel'e, Unity oyunları için ise Trivial Kart'a bakın.
Tuş bağlamalarınızı oluşturma
InputMap
oluşturarak ve InputMappingProvider
ile döndürerek tuş bağlamalarınızı kaydedin. Aşağıdaki örnekte bir InputMappingProvider
'nin ana hatları belirtilmiştir:
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
Giriş işlemlerinizi tanımlama
InputAction
sınıfı, bir anahtarı veya tuş kombinasyonunu bir oyun hareketiyle eşlemek için kullanılır. InputActions
, tüm InputActions
'lerde benzersiz kimliklere sahip olmalıdır.
Yeniden eşlemeyi destekliyorsanız InputActions
değerinin ne şekilde yeniden eşlenebileceğini tanımlayabilirsiniz. Oyununuz yeniden eşlemeyi desteklemiyorsa yeniden eşleme seçeneğini tüm InputActions
cihazlarınız için devre dışı bırakmanız gerekir. Ancak Giriş SDK'sı, InputMap
cihazınızda desteklemiyorsanız yeniden eşlemeyi devre dışı bırakacak kadar akıllıdır.
Bu örnekte,
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 );
İşlemler, fare girişlerini de temsil edebilir. Bu örnekte, Sol tıklama için Taşı işlemi ayarlanmıştır:
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 );
Tuş kombinasyonları, InputAction
öğenize birden fazla tuş kodu iletilerek belirtilir. Bu örnekte
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 );
Giriş SDK'sı, tek bir işlem için fare ve tuş düğmelerini birlikte kullanmanıza olanak tanır. Bu örnekte,
Kotlin
companion object { private val addWaypointInputAction = InputAction.create( "Add waypoint", InputActionsIds.ADD_WAYPOINT.ordinal.toLong(), InputControls.create( listOf(KeyEvent.KeyEvent.KEYCODE_TAB), listOf(InputControls.MOUSE_RIGHT_CLICK)), InputEnums.REMAP_OPTION_DISABLED) }
Java
private static final InputAction addWaypointInputAction = InputAction.create( "Add waypoint", InputActionsIds.ADD_WAYPOINT.ordinal(), InputControls.create( Collections.singletonList(KeyEvent.KEYCODE_TAB), Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK) ), InputEnums.REMAP_OPTION_DISABLED );
C#
private static readonly InputAction addWaypointInputAction = InputAction.Create( "Add waypoint", (long)InputEventIds.ADD_WAYPOINT, InputControls.Create( new[] { new Integer(AndroidKeyCode.KEYCODE_SPACE) }.ToJavaList(), new[] { new Integer((int)PlayMouseAction.MouseRightClick) }.ToJavaList() ), InputEnums.REMAP_OPTION_DISABLED );
InputAction aşağıdaki alanlara sahiptir:
ActionLabel
: Bu işlemi temsil etmek için kullanıcı arayüzünde gösterilen dize. Yerelleştirme otomatik olarak yapılmaz. Bu nedenle, yerelleştirmeyi önceden yapın.InputControls
: Bu işlemin kullandığı giriş denetimlerini tanımlar. Kontroller, yer paylaşımındaki tutarlı karakterlerle eşlenir.InputActionId
:InputAction
kimliğini ve sürümünü depolayanInputIdentifier
nesnesi (daha fazla bilgi için İzleme Anahtar Kimlikleri bölümüne bakın).InputRemappingOption
:InputEnums.REMAP_OPTION_ENABLED
veyaInputEnums.REMAP_OPTION_DISABLED
değerlerinden biri. İşlemin yeniden eşleme için etkinleştirilip etkinleştirilmeyeceğini tanımlar. Oyununuz yeniden eşlemeyi desteklemiyorsa bu alanı atlayabilir veya devre dışı bırakabilirsiniz.RemappedInputControls
: Yeniden eşleme etkinliklerinde kullanıcı tarafından ayarlanan yeniden eşlenen anahtarı okumak için kullanılan salt okunurInputControls
nesnesi (yeniden eşleme etkinlikleri hakkında bildirim almak için kullanılır).
InputControls
, bir işlemle ilişkili girişleri temsil eder ve aşağıdaki alanları içerir:
AndroidKeycodes
: Bir işlemle ilişkili klavye girişlerini temsil eden tam sayıların listesidir. Bunlar KeyEvent sınıfında veya Unity için AndroidKeycode sınıfında tanımlanır.MouseActions
: Bu işlemle ilişkili fare girişlerini temsil edenMouseAction
değerlerinin listesidir.
Giriş gruplarınızı tanımlama
InputActions
, gezinmeyi iyileştirmek ve yer paylaşımındaki bulunabilirliği kontrol etmek için InputGroups
kullanılarak mantıksal olarak ilişkili işlemlerle gruplandırılır. Her InputGroup
kimliğinin, oyununuzdaki tüm InputGroups
'ler için benzersiz olması gerekir.
Giriş işlemlerinizi gruplara ayırarak oyuncuların mevcut bağlamları için doğru tuş bağlamalarını bulmalarını kolaylaştırırsınız.
Yeniden eşlemeyi destekliyorsanız InputGroups
değerinin ne şekilde yeniden eşlenebileceğini tanımlayabilirsiniz. Oyununuz yeniden eşlemeyi desteklemiyorsa yeniden eşleme seçeneğini tüm InputGroups
cihazlarınız için devre dışı bırakmanız gerekir. Ancak Giriş SDK'sı, InputMap
cihazınızda yeniden eşlemeyi desteklemiyorsanız yeniden eşlemeyi devre dışı bırakacak kadar akıllıdır.
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 );
Aşağıdaki örnekte, yer paylaşımındaki Yol kontrolleri ve Menü kontrolleri giriş grupları gösterilmektedir:
InputGroup
aşağıdaki alanları içerir:
GroupLabel
: Yer paylaşımında gösterilecek ve bir dizi işlemi mantıksal olarak gruplandırmak için kullanılabilecek bir dize. Bu dize otomatik olarak yerelleştirilmez.InputActions
: Önceki adımda tanımladığınızInputAction
nesnelerinin listesi. Bu işlemlerin tümü grup başlığı altında görsel olarak gösterilir.InputGroupId
:InputGroup
öğesinin numara kimliğini ve sürümünü depolayanInputIdentifier
nesnesi. Daha fazla bilgi için İzleme Anahtar Kimlikleri bölümüne bakın.InputRemappingOption
:InputEnums.REMAP_OPTION_ENABLED
veyaInputEnums.REMAP_OPTION_DISABLED
değerlerinden biri. Devre dışı bırakılırsa bu gruba ait tümInputAction
öğelerin yeniden eşleme seçeneği etkin olsa bile yeniden eşleme devre dışı bırakılır. Bu seçenek etkinleştirilirse, ayrı ayrı işlemler tarafından devre dışı bırakılmadığı sürece bu gruba ait tüm işlemler yeniden atanabilir.
Giriş bağlamlarınızı tanımlama
InputContexts
, oyununuzun farklı sahneleri için farklı bir klavye kontrol grubu kullanmasına olanak tanır. Örnek:
- Menülerde gezinmek ve oyunda hareket etmek için farklı giriş grupları belirtebilirsiniz.
- Oyununuzdaki hareket şekline (ör. araba sürme veya yürüme) bağlı olarak farklı giriş kümeleri belirtebilirsiniz.
- Oyununuzun mevcut durumuna göre farklı giriş grupları belirtebilirsiniz (ör. bir üst dünyada gezinme ve tek bir seviyeyi oynama).
InputContexts
kullanılırken yer paylaşımında önce kullanılan bağlamın grupları gösterilir. Bu davranışı etkinleştirmek için oyununuz farklı bir sahneye her girdiğinde bağlamı ayarlamak üzere setInputContext()
işlevini çağırın. Aşağıdaki resimde bu davranış gösterilmektedir: "Araç kullanma" sahnesinde, Yol kontrolleri işlemleri yer paylaşımının üst kısmında gösterilmektedir. "Mağaza" menüsü açıldığında "Menü kontrolleri" işlemleri yer paylaşımının üst kısmında gösterilir.
Bu yer paylaşımı güncellemeleri, oyununuzun farklı noktalarında farklı bir InputContext
ayarlayarak yapılır. Bunu yapmak için:
InputActions
öğeleriniziInputGroups
kullanarak mantıksal olarak ilişkili işlemlerle gruplandırın- Bu
InputGroups
'leri oyununuzun farklı bölümleri için birInputContext
'e atayın
InputGroups
aynı anahtarın kullanıldığıInputContext
birbirine çelişen InputActions
sahip olamaz. Her InputGroup
öğesini tek bir InputContext
öğesine atamak iyi bir uygulamadır.
Aşağıdaki örnek kodda InputContext
mantığı gösterilmektedir:
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
aşağıdaki alanları içerir:
LocalizedContextLabel
: Bağlama ait grupları açıklayan bir dize.InputContextId
:InputContext
kimliğini ve sürümünü depolayanInputIdentifier
nesnesi (daha fazla bilgi için İzleme Anahtar Kimlikleri bölümüne bakın).ActiveGroups
: Bu bağlam etkin olduğunda kullanılacak ve yer paylaşımının üst kısmında gösterilecekInputGroups
öğelerinin listesi.
Giriş haritası oluşturma
InputMap
, bir oyunda bulunan tüm InputGroup
nesnelerinin ve dolayısıyla bir oyuncunun gerçekleştirebileceği tüm InputAction
nesnelerinin bir koleksiyonudur.
Tuş bağlamalarınızı raporlarken oyununuzda kullanılan tüm InputGroups
ile bir InputMap
oluşturursunuz.
Oyununuz yeniden eşlemeyi desteklemiyorsa yeniden eşleme seçeneğini devre dışı bırakın ve ayrılmış anahtarları boş bırakın.
Aşağıdaki örnekte, bir InputGroups
koleksiyonunu bildirmek için kullanılan bir InputMap
oluşturulmaktadır.
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
aşağıdaki alanları içerir:
InputGroups
: Oyununuz tarafından raporlanan InputGroups.setInputContext()
çağrısı yapılarak kullanılan mevcut gruplar belirtilmediği sürece gruplar yer paylaşımında sırayla gösterilir.MouseSettings
:MouseSettings
nesnesi, fare hassasiyetinin ayarlanabileceğini ve farenin y ekseninde ters çevrildiğini gösterir.InputMapId
:InputMap
kimliğini ve sürümünü depolayanInputIdentifier
nesnesi (daha fazla bilgi için İzleme Anahtarı Kimlikleri bölümüne bakın).InputRemappingOption
:InputEnums.REMAP_OPTION_ENABLED
veyaInputEnums.REMAP_OPTION_DISABLED
değerlerinden biri. Yeniden eşleme özelliğinin etkin olup olmadığını tanımlar.ReservedControls
: Kullanıcıların yeniden eşlemeye izin verilmeyenInputControls
değerlerinin listesi.
Anahtar kimliklerini izleme
InputAction
, InputGroup
, InputContext
ve InputMap
nesneleri, benzersiz bir sayı kimliği ve dize sürüm kimliği depolayan bir InputIdentifier
nesnesi içerir.
Nesnelerinizin dize sürümünü izlemek isteğe bağlıdır ancak InputMap
sürümlerinizi izlemek için önerilir. Dize sürümü sağlanmazsa dize boş olur. InputMap
nesneleri için dize sürümü gereklidir.
Aşağıdaki örnekte, InputActions
veya InputGroups
için bir dize sürümü atanmaktadır:
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
InputAction
nesnelerinin numara kimlikleri, InputMap
'nizdeki tüm InputActions
'ler arasında benzersiz olmalıdır. Benzer şekilde, InputGroup
nesne kimlikleri bir InputMap
içindeki tüm InputGroups
'ler için benzersiz olmalıdır. Aşağıdaki örnekte, nesnenizin benzersiz kimliklerini izlemek için enum
değerinin nasıl kullanılacağı gösterilmektedir:
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
aşağıdaki alanları içerir:
UniqueId
: Belirli bir giriş verisi grubunu benzersiz şekilde tanımlamak için ayarlanan benzersiz bir sayı kimliği.VersionString
: Giriş verileri değişikliklerinin 2 sürümü arasındaki giriş verisi sürümünü tanımlamak için ayarlanmış, kullanıcı tarafından okunabilen bir sürüm dizesi.
Yeniden eşleme etkinlikleri hakkında bildirim alma (İsteğe bağlı)
Oyununuzda kullanılan tuşlar hakkında bilgi edinmek için yeniden eşleme etkinlikleriyle ilgili bildirim alın. Bu sayede oyununuz, işlem kontrollerini görüntülemek için kullanılan oyun ekranında gösterilen öğeleri güncelleyebilir.
Aşağıdaki resimde,
Bu işlev, bir InputRemappingListener
geri çağırma işlevi kaydedilerek elde edilir. Bu özelliği uygulamak için bir InputRemappingListener
örneği kaydederek başlayın:
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
, kullanıcı tarafından kaydedilen yeniden eşlenen kontroller yüklendikten sonra ve kullanıcı tuşlarını her yeniden eşlediğinde başlatma sırasında bilgilendirilir.
Başlatma
InputContexts
kullanıyorsanız ilk sahneniz için kullanılan ilk bağlam da dahil olmak üzere her geçişte yeni bir bağlam ayarlayın. InputMap
'unuzu kaydettikten sonra InputContext
ayarını yapmanız gerekir.
Yeniden eşleme etkinlikleri hakkında bildirim almak için InputRemappingListeners
kullanıyorsanız InputMappingProvider
'nizi kaydettirmeden önce InputRemappingListener
'nizi kaydedin. Aksi takdirde oyununuz lansman sırasında önemli etkinlikleri kaçırabilir.
Aşağıdaki örnekte API'nin nasıl başlatılacağı gösterilmektedir:
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 } }
Düzenle
Oyununuz kapalıyken InputMappingProvider
örneğinizin ve tüm InputRemappingListener
örneklerinin kaydını silin. Giriş SDK'sı, bunu yapmamanız durumunda kaynakların sızınmasını önlemek için yeterince akıllı olsa da:
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
Oynatıcı deneyimini görüntülemek için yer paylaşımını manuel olarak açarak veya otomatik test ve doğrulama için adb kabuğunu kullanarak Giriş SDK'nızın uygulamasını test edebilirsiniz.
PC Üzerinde Google Play Games Emülatörü, giriş haritanızın doğruluğunu sık karşılaşılan hatalara karşı kontrol eder. Yinelenen benzersiz kimlikler, farklı giriş haritaları kullanma veya yeniden eşleme kurallarının başarısız olması (yeniden eşleme etkinse) gibi senaryolarda yer paylaşımında aşağıdaki hata mesajı gösterilir:
Komut satırında adb
kullanarak giriş SDK'sı uygulamanızı doğrulayın.
Geçerli giriş haritasını almak için aşağıdaki adb shell
komutunu kullanın (MY.PACKAGE.NAME
yerine oyununuzun adını girin):
adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME
InputMap
öğenizi başarıyla kaydettiyseniz buna benzer bir çıkış görürsünüz:
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
}
Yerelleştirme
Giriş SDK'sı, Android'in yerelleştirme sistemini kullanmaz. Sonuç olarak, InputMap
gönderirken yerelleştirilmiş dize sağlamanız gerekir. Oyun motorunuzun yerelleştirme sistemini de kullanabilirsiniz.
Proguard
Oyununuzu küçültmek için Proguard'ı kullanırken SDK'nın nihai paketinizden kaldırılmamasını sağlamak üzere Proguard yapılandırma dosyanıza aşağıdaki kuralları ekleyin:
-keep class com.google.android.libraries.play.hpe.** { *; }
-keep class com.google.android.libraries.play.games.inputmapping.** { *; }
Sırada ne var?
Giriş SDK'sını oyununuza entegre ettikten sonra PC Üzerinde Google Play Games ile ilgili diğer koşulları yerine getirmeye devam edebilirsiniz. Daha fazla bilgi için PC Üzerinde Google Play Games'i kullanmaya başlama başlıklı makaleyi inceleyin.