เอกสารนี้อธิบายวิธีตั้งค่าและแสดงอินพุต SDK ใน เกมที่รองรับ Google Play Games บน PC งานดังกล่าวรวมถึงการเพิ่ม SDK เกมของคุณ และสร้างแผนที่อินพุตที่มี การกำหนดการดำเนินการในเกมแก่ผู้ใช้
ก่อนเริ่มต้นใช้งาน
ก่อนที่จะเพิ่มอินพุต SDK ลงในเกม คุณต้องรองรับ แป้นพิมพ์และเมาส์โดยใช้ ระบบอินพุต
Input SDK ให้ข้อมูลเกี่ยวกับ Google Play Games บน PC สิ่งที่เกมของคุณใช้ควบคุม เพื่อแสดงต่อผู้ใช้ นอกจากนี้ยังสามารถ มีตัวเลือกให้ผู้ใช้รีแมปแป้นพิมพ์ได้
ตัวควบคุมแต่ละตัวคือ InputAction
(เช่น "J" สําหรับ "Jump") และคุณจัดระเบียบ
InputActions
ไปยัง InputGroups
InputGroup
อาจแสดงถึง
ในเกมของคุณ เช่น "ขับรถ" หรือ "เดินเท้า" หรือ "เมนูหลัก" นอกจากนี้คุณยัง
ใช้ InputContexts
เพื่อระบุว่ากลุ่มใดมีการใช้งาน ณ จุดต่างๆ ของ
เกมนี้
คุณสามารถเปิดใช้การรีแมปแป้นพิมพ์ให้คุณโดยอัตโนมัติ แต่ถ้า คุณต้องการให้มีอินเทอร์เฟซการรีแมปการควบคุมของคุณเอง คุณก็สามารถปิดใช้ การแมป SDK อินพุตใหม่
แผนภาพลำดับต่อไปนี้อธิบายวิธีการทำงานของ API ของอินพุต SDK
เมื่อเกมใช้ SDK อินพุต ตัวควบคุมของคุณจะปรากฏขึ้น ในการวางซ้อน Google Play Games บน PC
การวางซ้อน Google Play Games บน PC
การวางซ้อน Google Play Games บน PC ("การวางซ้อน") จะแสดงตัวควบคุม ที่กำหนดโดยเกมของคุณ ผู้ใช้เข้าถึงการวางซ้อนได้ตลอดเวลาโดย กด Shift + Tab
แนวทางปฏิบัติแนะนำสำหรับการออกแบบการเชื่อมโยงคีย์
โปรดพิจารณาแนวทางปฏิบัติแนะนำต่อไปนี้เมื่อออกแบบการเชื่อมโยงคีย์
- จัดกลุ่ม
InputActions
เป็นInputGroups
ที่มีความเกี่ยวข้องทางตรรกะเพื่อปรับปรุง การนำทางและการค้นพบได้ของตัวควบคุมระหว่างการเล่นเกม - กำหนด
InputGroup
แต่ละรายการให้กับInputContext
ไม่เกิน 1 รายการ เม็ดเล็กละเอียดInputMap
ส่งผลให้ประสบการณ์การใช้งานที่ดีขึ้นสำหรับการนำทางตัวควบคุมใน การซ้อนทับ - สร้าง
InputContext
สำหรับฉากแต่ละประเภทของเกม โดยปกติแล้ว คุณจะใช้InputContext
รายการเดียวสำหรับ "เมนูแบบเมนู" ทั้งหมดก็ได้ ต่างๆ ใช้InputContexts
ที่แตกต่างกันสำหรับมินิเกมในเกมหรือสำหรับ การควบคุมสำรองสำหรับฉากเดียว - หากการดำเนินการ 2 รายการได้รับการออกแบบมาให้ใช้คีย์เดียวกันภายใต้
InputContext
ใช้สตริงป้ายกำกับ เช่น "โต้ตอบ / เริ่มทำงาน" - หาก 2 แป้นได้รับการออกแบบมาเพื่อเชื่อมโยงกับ
InputAction
เดียวกัน ให้ใช้ 2InputActions
ที่แตกต่างกันที่ทำงานเดียวกันในเกม คุณสามารถ ใช้สตริงป้ายกำกับเดียวกันสำหรับInputActions
ทั้ง 2 รายการ แต่รหัสต้องเป็น แตกต่างกัน - หากมีการใช้แป้นกดร่วมกับชุดแป้น ให้พิจารณาใช้แป้นเดียว
InputAction
โดยใช้แป้นกดร่วม แทนที่จะเป็นInputActions
หลายรายการที่ รวมคีย์ตัวปรับแต่ง (เช่น ใช้ Shift และ W, A, S, D แทน Shift + W, Shift + A, Shift + S, Shift + D) - ระบบจะปิดใช้การแมปอินพุตใหม่โดยอัตโนมัติเมื่อผู้ใช้เขียนลงในข้อความ
ด้วย ทำตามแนวทางปฏิบัติแนะนำสำหรับการใช้ช่องข้อความ Android
ว่า Android สามารถตรวจหาช่องข้อความในเกมและป้องกันไม่ให้มีคีย์ที่รีแมปได้
ไม่ให้รบกวนพวกเขาได้ หากเกมของคุณต้องใช้ข้อความที่ไม่เป็นไปตามรูปแบบ
ฟิลด์ที่คุณสามารถใช้
setInputContext()
กับInputContext
ที่มีเอลิเมนต์ รายการว่างของInputGroups
เพื่อปิดใช้การรีแมปด้วยตนเอง - หากเกมของคุณรองรับการรีแมป ให้ลองอัปเดตการเชื่อมโยงคีย์ การดำเนินการที่มีความละเอียดอ่อนซึ่งขัดแย้งกับเวอร์ชันที่ผู้ใช้บันทึกไว้ หลีกเลี่ยง เปลี่ยนรหัสของตัวควบคุมที่มีอยู่ เมื่อเป็นไปได้
ฟีเจอร์การรีแมป
Google Play Games บน PC รองรับการรีแมปการควบคุมแป้นพิมพ์โดยอิงตามแป้น
การเชื่อมโยงเกมที่คุณให้โดยใช้ SDK อินพุต ขั้นตอนนี้เป็นแบบไม่บังคับและ
สามารถปิดใช้ได้ทั้งหมด เช่น คุณอาจต้องให้มีแป้นพิมพ์ของคุณเอง
การรีแมปอินเทอร์เฟซ หากต้องการปิดใช้การรีแมปสำหรับเกม คุณเพียงแค่ต้องระบุ
ตัวเลือกการรีแมปถูกปิดใช้งานสำหรับ InputMap
ของคุณ (โปรดดู
สร้าง InputMap สําหรับข้อมูลเพิ่มเติม)
ในการเข้าถึงฟีเจอร์นี้ ผู้ใช้ต้องเปิดการวางซ้อนแล้วคลิกการทำงาน ที่ต้องการรีแมป หลังจากทุกกิจกรรมรีแมป Google Play Games บน PC แมป ตัวควบคุมแต่ละรายการที่ผู้ใช้รีแมปไปเป็นการควบคุมเริ่มต้นที่เกมของคุณคาดว่าจะทำ เพื่อให้เกมของคุณไม่จำเป็นต้องรับรู้ถึงการรีแมปของผู้เล่น คุณ สามารถเลือกอัปเดตเนื้อหาที่ใช้แสดงตัวควบคุมแป้นพิมพ์ใน เกมได้โดยการเพิ่ม Callback สำหรับรีแมปเหตุการณ์
Google Play Games บน PC จะจัดเก็บการควบคุมที่รีแมปในเครื่องของผู้ใช้แต่ละคน เปิดใช้งานการควบคุมอย่างต่อเนื่องในเซสชันการเล่นเกม ระบบจัดเก็บข้อมูลนี้ไว้ บนดิสก์เท่านั้นสำหรับแพลตฟอร์ม PC และจะไม่ส่งผลต่อประสบการณ์การใช้งานบนอุปกรณ์เคลื่อนที่ โดยข้อมูลการควบคุมจะถูกลบเมื่อผู้ใช้ถอนการติดตั้งหรือติดตั้ง Google Play Games บน PC อีกครั้ง โดยข้อมูลนี้จะไม่คงอยู่ในอุปกรณ์ PC หลายเครื่อง
โปรดหลีกเลี่ยงข้อจำกัดต่อไปนี้เพื่อรองรับฟีเจอร์การรีแมปในเกม
ข้อจำกัดของการรีแมป
คุณปิดใช้ฟีเจอร์การรีแมปในเกมได้ หากการเชื่อมโยงแป้นมี กรณีต่อไปนี้
InputActions
หลายคีย์ที่ไม่ได้เขียนด้วยแป้นกดร่วม + a ไม่มีตัวแก้ไข ตัวอย่างเช่น Shift + A ถือว่าใช้ได้ แต่เป็น A + B Ctrl + Alt หรือ Shift + A + Tab ไม่ถูกต้องInputMap
มีInputActions
,InputGroups
หรือInputContexts
โดยใช้รหัสที่ไม่ซ้ำกันซ้ำๆ
ข้อจำกัดของการรีแมป
ให้พิจารณาสิ่งต่อไปนี้เมื่อออกแบบการเชื่อมโยงคีย์สำหรับการรีแมป ข้อจำกัด:
- ไม่รองรับการรีแมปกับแป้นที่กดร่วมกัน ตัวอย่างเช่น ผู้ใช้ไม่สามารถ รีแมป Shift + A เป็น Ctrl + B หรือ A เป็น Shift + A
- ไม่รองรับการรีแมปสำหรับ
InputActions
ที่ใช้ปุ่มเมาส์ สำหรับ ตัวอย่างเช่น คุณจะแมป Shift + คลิกขวาไม่ได้
ทดสอบการรีแมปคีย์ใน Google Play Games บน PC
คุณเปิดใช้ฟีเจอร์การรีแมปในโปรแกรมจําลอง Google Play Games บน PC ได้ทุกเมื่อ ด้วยการออกคำสั่ง adb ต่อไปนี้
adb shell dumpsys input_mapping_service --set RemappingFlagValue true
การวางซ้อนจะเปลี่ยนไปดังในรูปภาพต่อไปนี้:
เพิ่ม SDK
ติดตั้งอินพุต SDK ตามแพลตฟอร์มการพัฒนาของคุณ
Java และ Kotlin
รับอินพุต SDK สำหรับ Java หรือ Kotlin โดยการเพิ่ม Dependency ไปยัง
ไฟล์ build.gradle
ระดับโมดูล:
dependencies {
implementation 'com.google.android.libraries.play.games:inputmapping:1.1.0-beta'
...
}
เอกภาพ
Input SDK เป็นแพ็กเกจ Unity มาตรฐานที่มีทรัพยากร Dependency หลายรายการ
จำเป็นต้องติดตั้งแพ็กเกจที่มีการอ้างอิงทั้งหมด ซึ่งทำได้หลายวิธี เพื่อติดตั้งแพ็กเกจ
ติดตั้ง .unitypackage
ดาวน์โหลดไฟล์ unitypackage ของ Input SDK
พร้อมทรัพยากร Dependency ทั้งหมด คุณจะติดตั้ง .unitypackage
ได้โดยเลือก
ชิ้นงาน > นำเข้าแพ็กเกจ > แพ็กเกจที่กำหนดเอง และค้นหาไฟล์ที่คุณดาวน์โหลด
ติดตั้งโดยใช้ UPM
หรือคุณอาจติดตั้งแพ็กเกจโดยใช้
เครื่องมือจัดการแพ็กเกจของ Unity โดย
ดาวน์โหลด .tgz
และติดตั้งทรัพยากร Dependency ต่อไปนี้
- 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
ติดตั้งโดยใช้ OpenUPM
คุณสามารถติดตั้งแพ็กเกจโดยใช้ OpenUPM
$ openupm add com.google.android.libraries.play.games.inputmapping
เกมตัวอย่าง
ดูตัวอย่างวิธีผสานรวมกับ SDK อินพุตได้ที่ อุโมงค์ AGDK สำหรับเกม Kotlin หรือ Java และ ไพ่ Trivial Kart สำหรับเกม Unity
สร้างการเชื่อมโยงคีย์
ลงทะเบียนการเชื่อมโยงคีย์โดยการสร้าง InputMap
และแสดงผลด้วย
InputMappingProvider
ตัวอย่างต่อไปนี้สรุป
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
กำหนดการดำเนินการป้อนข้อมูล
คลาส InputAction
ใช้เพื่อแมปคีย์หรือชุดคีย์กับเกม
การดำเนินการ InputActions
ต้องมีรหัสที่ไม่ซ้ำกันใน InputActions
ทั้งหมด
หากคุณรองรับการรีแมป คุณสามารถกำหนดว่า InputActions
สามารถทำอะไรได้บ้าง
รีแมปแล้ว หากเกมของคุณไม่รองรับการรีแมป คุณควรตั้งค่าการรีแมป
ตัวเลือกถูกปิดใช้งานสำหรับ InputActions
ทั้งหมดของคุณ แต่อินพุต SDK คือ
มีความฉลาดพอที่จะปิดการรีแมปหากคุณไม่สนับสนุนการรีแมป
InputMap
ตัวอย่างนี้แมปคีย์
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 );
การทำงานสามารถแสดงการป้อนข้อมูลด้วยเมาส์ได้เช่นกัน ตัวอย่างนี้ตั้งค่าคลิกซ้ายเป็น การดำเนินการย้าย
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 );
จะมีการระบุชุดคีย์ด้วยการส่งรหัสคีย์หลายรหัสไปยัง
InputAction
ในตัวอย่างนี้
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 );
อินพุต SDK ทำให้คุณสามารถผสม ปุ่มเมาส์และปุ่มหลักเข้าด้วยกัน
การกระทำเดียว ตัวอย่างนี้ระบุว่า
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 มีฟิลด์ต่อไปนี้
ActionLabel
: สตริงที่แสดงใน UI เพื่อแสดงการดำเนินการนี้ การแปลจะไม่สามารถทำได้โดยอัตโนมัติ ดังนั้นให้ปรับ ด้านหน้าInputControls
: กำหนดการควบคุมอินพุตที่การดำเนินการนี้ใช้ ควบคุมแผนที่กับรูปอักขระที่สอดคล้องกันในการวางซ้อนInputActionId
: ออบเจ็กต์InputIdentifier
รายการที่จัดเก็บรหัสหมายเลขและเวอร์ชัน ของInputAction
(ดูรหัสคีย์การติดตามสำหรับข้อมูลเพิ่มเติม ข้อมูล)InputRemappingOption
: หนึ่งในInputEnums.REMAP_OPTION_ENABLED
หรือInputEnums.REMAP_OPTION_DISABLED
ระบุว่ามีการเปิดใช้งานการดำเนินการหรือไม่ รีแมป หากเกมไม่รองรับการรีแมป คุณสามารถข้ามช่องนี้หรือ ก็แค่ตั้งค่าปิดใช้งานRemappedInputControls
: ออบเจ็กต์InputControls
แบบอ่านอย่างเดียวที่ใช้อ่าน คีย์ที่รีแมปที่ผู้ใช้กำหนดไว้ในเหตุการณ์การรีแมป (ใช้สำหรับ การได้รับการแจ้งเตือนเมื่อเกิดเหตุการณ์รีแมป)
InputControls
แสดงอินพุตที่เชื่อมโยงกับการดำเนินการและมีเมธอด
ฟิลด์ต่อไปนี้:
AndroidKeycodes
: เป็นรายการจำนวนเต็มที่แสดงการป้อนข้อมูลด้วยแป้นพิมพ์ ที่เชื่อมโยงกับการทำงาน ซึ่งมีการกำหนดไว้ในส่วน เหตุการณ์สําคัญ หรือคลาส AndroidKeycode สำหรับ UnityMouseActions
: เป็นรายการค่าMouseAction
ที่แสดงอินพุตจากเมาส์ ที่เชื่อมโยงกับการดำเนินการนี้
กำหนดกลุ่มอินพุต
จัดกลุ่ม InputActions
ด้วยการดำเนินการที่เกี่ยวข้องกันอย่างสมเหตุสมผลโดยใช้ InputGroups
เพื่อ
ปรับปรุงการนำทางและควบคุมการค้นพบได้ในการวางซ้อน ชิ้น
รหัส InputGroup
ต้องไม่ซ้ำกันสำหรับ InputGroups
ทั้งหมดในเกมของคุณ
การจัดระเบียบการป้อนข้อมูลให้เป็นกลุ่มจะช่วยให้ผู้เล่นทำสิ่งต่างๆ ได้ง่ายขึ้น ค้นหาการเชื่อมโยงคีย์ที่ถูกต้องสำหรับบริบทปัจจุบัน
หากคุณรองรับการรีแมป คุณสามารถกำหนดว่า InputGroups
สามารถทำอะไรได้บ้าง
รีแมปแล้ว หากเกมของคุณไม่รองรับการรีแมป คุณควรตั้งค่าการรีแมป
ตัวเลือกถูกปิดใช้งานสำหรับ InputGroups
ทั้งหมดของคุณ แต่อินพุต SDK คือ
มีความฉลาดพอที่จะปิดการรีแมปหากคุณไม่สนับสนุนการรีแมป
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 );
ตัวอย่างต่อไปนี้แสดงการควบคุมถนนและการควบคุมเมนู กลุ่มอินพุตในการวางซ้อน:
InputGroup
มีช่องต่อไปนี้
GroupLabel
: สตริงที่จะแสดงในโฆษณาซ้อนทับที่ใช้เพื่อ จัดกลุ่มชุดของการดำเนินการอย่างมีตรรกะ ระบบจะไม่รวมสตริงนี้โดยอัตโนมัติ แปลแล้วInputActions
: รายการInputAction
ออบเจ็กต์ที่คุณกำหนดก่อนหน้านี้ ครั้งแรก การดำเนินการเหล่านี้ทั้งหมดจะแสดงอยู่ใต้ส่วนหัวของกลุ่มInputGroupId
: ออบเจ็กต์InputIdentifier
ที่จัดเก็บรหัสหมายเลขและ ของInputGroup
ดูรหัสคีย์การติดตามสำหรับ ข้อมูลเพิ่มเติมInputRemappingOption
: หนึ่งในInputEnums.REMAP_OPTION_ENABLED
หรือInputEnums.REMAP_OPTION_DISABLED
หากปิดใช้ ระบบจะInputAction
ทั้งหมด ออบเจ็กต์ที่อยู่ในกลุ่มนี้จะถูกปิดใช้การรีแมป ระบุว่ามีการเปิดใช้ตัวเลือกการแมปใหม่ หากเปิดใช้ การดำเนินการทั้งหมดที่เป็นของ ไปยังกลุ่มนี้ซ้ำได้ ยกเว้นกรณีที่บุคคลปิดใช้งานระบุไว้ การดำเนินการ
กำหนดบริบทสำหรับอินพุต
InputContexts
อนุญาตให้เกมใช้ชุดการควบคุมแป้นพิมพ์ที่ต่างออกไปสำหรับ
ในฉากต่างๆ ในเกม เช่น
- คุณอาจระบุชุดอินพุตที่ต่างกันสำหรับการไปยังเมนูและการย้าย ในเกม
- คุณสามารถระบุชุดอินพุตต่างๆ ได้ โดยขึ้นอยู่กับโหมดการเคลื่อนไหว ในเกม เช่น การขับรถเทียบกับการเดิน
- คุณสามารถระบุชุดอินพุตต่างๆ ตามสถานะปัจจุบันของข้อมูล เช่น เดินทางข้ามโลกหรือเล่นเกมแต่ละด่าน
เมื่อใช้ InputContexts
โฆษณาซ้อนทับจะแสดงกลุ่มของบริบทก่อน
ที่ใช้งานอยู่ หากต้องการเปิดใช้ลักษณะการทำงานนี้ ให้เรียก setInputContext()
เพื่อตั้งค่า
เมื่อใดก็ตามที่เกมของคุณเข้าสู่ฉากอื่นๆ รูปภาพต่อไปนี้
แสดงให้เห็นพฤติกรรมนี้: ขณะขับรถ การควบคุมถนน
จะแสดงด้านบนของการวางซ้อน เมื่อเปิด "ร้านค้า"
"การควบคุมเมนู" จะแสดงด้านบนของการวางซ้อน
การอัปเดตการวางซ้อนเหล่านี้สามารถทำได้โดยการตั้งค่า InputContext
ที่แตกต่างกันที่
แต้มต่างๆ ในเกมของคุณ หากต้องการทำสิ่งต่อไปนี้
- จัดกลุ่ม
InputActions
ด้วยการดำเนินการที่เกี่ยวข้องเชิงตรรกะโดยใช้InputGroups
- กำหนด
InputGroups
เหล่านี้ให้กับInputContext
สำหรับส่วนต่างๆ ของ เกมของคุณ
InputGroups
ที่เป็นของสถานที่เดียวกันInputContext
ไม่สามารถมีข้อขัดแย้งได้
InputActions
ที่ใช้คีย์เดียวกัน คุณควรมอบหมาย
InputGroup
เป็น InputContext
รายการเดียว
โค้ดตัวอย่างต่อไปนี้แสดงตรรกะ 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
มีช่องต่อไปนี้
LocalizedContextLabel
: สตริงที่อธิบายกลุ่มที่อยู่ใน บริบทInputContextId
: ออบเจ็กต์InputIdentifier
รายการที่จัดเก็บรหัสหมายเลขและเวอร์ชัน ของInputContext
(ดูรหัสคีย์การติดตามสำหรับข้อมูลเพิ่มเติม ข้อมูล)ActiveGroups
: รายการInputGroups
ที่จะใช้และแสดงที่ด้านบน ของการวางซ้อนเมื่อบริบทนี้ทำงานอยู่
สร้างแผนที่อินพุต
InputMap
คือคอลเล็กชันของออบเจ็กต์ InputGroup
ทั้งหมดที่มีอยู่ใน
ดังนั้นวัตถุ InputAction
ทั้งหมดที่ผู้เล่นคาดหวังว่าจะได้
แสดง
ขณะรายงานการเชื่อมโยงคีย์ คุณจะต้องสร้าง InputMap
ที่มีการเชื่อมโยง
ใช้ไป InputGroups
ในเกม
หากเกมไม่รองรับการรีแมป ให้ตั้งค่าตัวเลือกการรีแมปปิดใช้และ คีย์ที่สงวนไว้ว่างเปล่า
ตัวอย่างต่อไปนี้สร้าง InputMap
ที่ใช้ในการรายงานคอลเล็กชัน
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
มีช่องต่อไปนี้
InputGroups
: InputGroups ที่รายงานโดยเกมของคุณ กลุ่มต่างๆ ได้แก่ แสดงตามลำดับในการวางซ้อน ยกเว้นที่ระบุกลุ่มปัจจุบันใน ใช้โทรหาsetInputContext()
MouseSettings
: วัตถุMouseSettings
ระบุว่าความไวของเมาส์ และเมาส์ก็กลับอยู่บนแกน YInputMapId
: ออบเจ็กต์InputIdentifier
รายการที่จัดเก็บรหัสหมายเลขและเวอร์ชันของInputMap
(ดูรหัสคีย์การติดตามสำหรับข้อมูลเพิ่มเติม ข้อมูล)InputRemappingOption
: หนึ่งในInputEnums.REMAP_OPTION_ENABLED
หรือInputEnums.REMAP_OPTION_DISABLED
กำหนดว่าคุณลักษณะการรีแมปคือ เปิดอยู่ReservedControls
: รายชื่อInputControls
ที่ผู้ใช้จะไม่ได้รับอนุญาตให้ รีแมป
รหัสคีย์การติดตาม
ออบเจ็กต์ InputAction
, InputGroup
, InputContext
และ InputMap
ประกอบด้วย
ออบเจ็กต์ InputIdentifier
ที่จัดเก็บรหัสหมายเลขที่ไม่ซ้ำกันและรหัสเวอร์ชันของสตริง
คุณเลือกที่จะติดตามเวอร์ชันสตริงของออบเจ็กต์หรือไม่ก็ได้ แต่เราขอแนะนำให้ติดตาม
เวอร์ชันของ InputMap
หากไม่ได้ระบุเวอร์ชันสตริง
สตริงว่างเปล่า ออบเจ็กต์ InputMap
รายการต้องมีเวอร์ชันสตริง
ตัวอย่างต่อไปนี้กำหนดเวอร์ชันสตริงให้กับ InputActions
หรือ
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
รหัสหมายเลขวัตถุ InputAction
รายการต้องไม่ซ้ำกันใน InputActions
ทั้งหมดใน
InputMap
ของคุณ ในทำนองเดียวกัน รหัสออบเจ็กต์ InputGroup
ต้องไม่ซ้ำกันในทุกผลิตภัณฑ์
InputGroups
ใน InputMap
ตัวอย่างต่อไปนี้สาธิตวิธีใช้
enum
เพื่อติดตามรหัสที่ไม่ซ้ำกันของออบเจ็กต์
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
มีช่องต่อไปนี้
UniqueId
: ชุดรหัสตัวเลขที่ไม่ซ้ำกันเพื่อระบุชุดอินพุตที่ระบุอย่างชัดเจน ข้อมูลได้อย่างไม่ซ้ำกันVersionString
: ชุดสตริงเวอร์ชันที่มนุษย์อ่านได้เพื่อระบุเวอร์ชัน ของข้อมูลอินพุตระหว่างการเปลี่ยนแปลงข้อมูลอินพุต 2 เวอร์ชัน
รับการแจ้งเตือนเกี่ยวกับการรีแมปกิจกรรม (ไม่บังคับ)
รับการแจ้งเตือนเมื่อเกิดเหตุการณ์ที่รีแมปเพื่อรับทราบข้อมูลเกี่ยวกับคีย์ที่ใช้ใน เกมของคุณ การดำเนินการนี้จะช่วยให้เกมของคุณอัปเดตเนื้อหาที่แสดงบนหน้าจอเกมได้ ซึ่งใช้เพื่อแสดงส่วนควบคุมการดำเนินการ
รูปภาพต่อไปนี้แสดงตัวอย่างของลักษณะการทำงานนี้ ซึ่งหลังจากรีแมป
แป้น
ฟังก์ชันนี้จะทำได้โดยการลงทะเบียน InputRemappingListener
Callback ในการนำคุณสมบัตินี้ไปใช้ ให้เริ่มด้วยการลงทะเบียน
อินสแตนซ์ 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
จะได้รับการแจ้งเตือนเมื่อเปิดใช้งานหลังจากโหลด
การควบคุมที่รีแมปที่ผู้ใช้บันทึกไว้ และทุกครั้งที่ผู้ใช้แมปแป้นของตนซ้ำ
การเริ่มต้น
หากคุณใช้ InputContexts
ให้กำหนดบริบทสำหรับแต่ละ
การเปลี่ยนไปยังฉากใหม่ รวมถึงบริบทแรกที่ใช้ในการเริ่มต้น
ด้วย คุณต้องตั้งค่า InputContext
หลังจากที่ลงทะเบียน
InputMap
หากคุณใช้ InputRemappingListeners
เพื่อรับการแจ้งเตือนเกี่ยวกับเหตุการณ์การรีแมป
ให้จดทะเบียน InputRemappingListener
ก่อนที่จะลงทะเบียน
InputMappingProvider
ไม่เช่นนั้นเกมอาจพลาดเหตุการณ์สำคัญในระหว่าง
เวลาเปิดตัว
ตัวอย่างต่อไปนี้แสดงวิธีเริ่มต้น 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 } }
ล้างข้อมูล
ยกเลิกการลงทะเบียนอินสแตนซ์ InputMappingProvider
และ InputRemappingListener
อินสแตนซ์เมื่อปิดเกมของคุณ แม้ว่า SDK อินพุตจะอัจฉริยะ
เพื่อป้องกันการรั่วไหลของทรัพยากรได้ หากไม่
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 } }
ทดสอบ
คุณทดสอบการใช้งาน Input SDK ได้โดยเปิด หน้าต่างวางซ้อนเพื่อดูประสบการณ์ของโปรแกรมเล่น หรือผ่านเชลล์ adb สำหรับการทดสอบและการยืนยันอัตโนมัติ
โปรแกรมจําลอง Google Play Games บน PC จะตรวจสอบความถูกต้องของแผนที่ที่คุณป้อน
เทียบกับข้อผิดพลาดที่พบบ่อย สำหรับสถานการณ์ เช่น รหัสที่ไม่ซ้ำที่ซ้ำกัน การใช้
การแมปอินพุตหรือล้มเหลวในกฎการรีแมป (หากเปิดใช้การแมปใหม่)
การวางซ้อนแสดงข้อความแสดงข้อผิดพลาดดังที่ระบุด้านล่าง
ยืนยันการติดตั้งใช้งาน Input SDK โดยใช้ adb
ที่บรรทัดคำสั่ง
หากต้องการรับแมปอินพุตปัจจุบัน ให้ใช้คำสั่ง adb shell
ต่อไปนี้ (แทนที่
MY.PACKAGE.NAME
ด้วยชื่อเกมของคุณ):
adb shell dumpsys input_mapping_service --get MY.PACKAGE.NAME
คุณจะเห็นเอาต์พุตในลักษณะนี้หากคุณลงทะเบียน
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
}
การแปล
Input SDK ไม่ได้ใช้ระบบการแปลของ Android เพื่อ
คุณต้องระบุสตริงที่แปลแล้วเมื่อส่ง InputMap
คุณ
ก็อาจใช้ระบบการแปลของเครื่องเกมด้วย
โปรการ์ด
เมื่อใช้ Proguard เพื่อลดขนาดเกม ให้เพิ่มกฎต่อไปนี้ ไฟล์การกำหนดค่า Proguard เพื่อให้แน่ใจว่า SDK จะไม่ถูกตัดออกจาก แพ็กเกจสุดท้าย:
-keep class com.google.android.libraries.play.hpe.** { *; }
-keep class com.google.android.libraries.play.games.inputmapping.** { *; }
ขั้นต่อไปคืออะไร
หลังจากผสานรวม Input SDK เข้ากับเกมแล้ว ให้ดำเนินการต่อ ตามข้อกำหนดที่เหลือของ Google Play Games บน PC สำหรับข้อมูลเพิ่มเติม ดูหัวข้อเริ่มต้นใช้งาน Google Play Games บน PC