Google Play 게임즈는 오픈 베타 버전입니다.

입력 SDK 시작하기

이 주제에서는 Google Play 게임즈를 지원하는 게임에서 입력 SDK 오버레이를 설정하고 표시하는 방법을 설명합니다. 게임에 SDK를 추가하고 사용자 입력 할당에 관한 게임 동작이 포함된 입력 맵을 생성하는 등의 작업이 실행됩니다. 키 바인딩 변경사항을 지원하는 게임의 경우 변경사항도 추적하고 SDK와 동기화해야 합니다.

시작하기 전에

입력 SDK를 게임에 추가하기 전에 키보드 및 마우스 지원을 추가해야 합니다.

SDK 추가

입력 SDK는 아직 다운로드할 수 없습니다. 자바 및 Kotlin 프로젝트의 경우 Maven 종속 항목으로 제공되고 Unity 개발자의 경우 unitypackagetgz로 제공됩니다.

새로운 SDK에 가장 먼저 액세스하려면 신청하시기 바랍니다.

입력 매핑 생성

입력 매핑은 입력 SDK 오버레이에 표시할 사용자 입력 할당에 관한 게임 동작을 나타냅니다. 입력 매핑을 생성하려면 InputMap을 빌드한 후 InputMappingProvider와 함께 반환해야 합니다.

다음은 InputMappingProvider의 개요를 보여주는 예시입니다.

Kotlin

class MyInputMapProvider : InputMappingProvider() {
    override fun onProvideInputMap(): InputMap {
        TODO("Not yet implemented")
    }
}

자바

public class MyInputMapProvider extends InputMappingProvider {
    @NonNull
    @Override
    public InputMap onProvideInputMap() {
        // TODO: return an InputMap
    }
}

C#

private class MyInputMappingProvider : InputMappingProvider
{
    public InputMap OnProvideInputMap()
    {
        // TODO("Not yet implemented")
    }
}

다음 섹션에서는 InputMappingProvider에서 반환할 InputMap을 만드는 방법을 설명합니다.

입력 작업 정의

InputAction 클래스는 키 또는 키 조합을 게임 동작에 매핑하는 데 사용합니다.

다음 예시에서는 space 키를 점프 동작에 매핑합니다.

Kotlin

val jumpInputAction = InputAction.create(
    "Jump",
    InputEventIds.JUMP.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SPACE),
        emptyList()
    )
)

자바

InputAction jumpInputAction = InputAction.create(
        "Jump",
        InputEventIds.JUMP.ordinal(),
        InputControls.create(
                Collections.singletonList(KeyEvent.KEYCODE_SPACE),
                Collections.emptyList()
        )
);

C#

var jumpInputAction = new InputAction
{
    ActionLabel = "Jump",
    UniqueId = (int)InputEventIds.Jump,
    InputControls = new InputControls
    {
        AndroidKeycodes = new[]
        {
            AndroidKeyCode.KEYCODE_SPACE
        }
    }
};

점프 동작이 스페이스 키에 바인딩되어 있음을 나타내는 입력 오버레이 스크린샷

동작은 마우스 입력도 나타낼 수 있습니다. 다음 예시는 right click을 이동 동작으로 설정합니다.

Kotlin

val cmbMove = InputAction.create(
    "Move",
    InputEventIds.CMB_MOVE.id,
    InputControls.create(
        emptyList(),
        listOf(InputControls.MOUSE_RIGHT_CLICK)
    )
)

자바

InputAction cmbMove = InputAction.create(
        "Move",
        InputEventIds.CMB_MOVE.ordinal(),
        InputControls.create(
                Collections.emptyList(),
                Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK)
        )
);

C#

var cmbMove = new InputAction
{
    ActionLabel = "Move",
    UniqueId = (int)InputEventIds.CmbMove,
    InputControls = new InputControls
    {
        MouseActions = new[]
        {
            MouseAction.MouseRightClick
        }
    }
};

이동 동작이 마우스 오른쪽 버튼으로 클릭과 바인딩되는 입력 오버레이 스크린샷

키 조합은 InputAction에 여러 키 코드를 전달하여 지정됩니다. 다음 예시에서 Space+Shift는 대시 동작에 매핑되며 Space 키가 점프에 매핑된 경우에도 작동합니다.

Kotlin

val cmbDash = InputAction.create(
    "Dash",
    InputEventIds.CMB_DASH.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SPACE, KeyEvent.KEYCODE_SHIFT_LEFT),
        emptyList()
    )
)

자바

InputAction cmbDash = InputAction.create(
        "Dash",
        InputEventIds.CMB_DASH.ordinal(),
        InputControls.create(
                Arrays.asList(KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SPACE),
                Collections.emptyList()
        )
);

C#

var cmbDash = new InputAction
{
    ActionLabel = "Dash",
    UniqueId = (int)InputEventIds.CmbDash,
    InputControls = new InputControls
    {
        AndroidKeycodes = new[]
        {
            AndroidKeyCode.KEYCODE_SPACE, AndroidKeyCode.KEYCODE_SHIFT_LEFT
        }
    }
};

Shift+Space가 대시 동작에 바인딩된 입력 오버레이의 스크린샷

입력 SDK를 사용하면 마우스와 키 버튼을 함께 사용하여 단일 명령어를 실행할 수 있습니다. 다음 예시는 shiftright-click을 함께 누르면 이 게임에 경유지를 추가함을 나타냅니다.

Kotlin

val cmbWaypoint = InputAction.create(
    "Add Waypoint",
    InputEventIds.CMB_WAYPOINT.id,
    InputControls.create(
        listOf(KeyEvent.KEYCODE_SHIFT_LEFT),
        listOf(InputControls.MOUSE_RIGHT_CLICK)
    )
)

자바

InputAction cmbWaypoint = InputAction.create(
        "Add Waypoint",
        InputEventIds.CMB_WAYPOINT.ordinal(),
        InputControls.create(
                Collections.singletonList(KeyEvent.KEYCODE_SHIFT_LEFT),
                Collections.singletonList(InputControls.MOUSE_RIGHT_CLICK)
        )
);

C#

var cmbWaypoint = new InputAction
{
    ActionLabel = "Add Waypoint",
    UniqueId = (int)InputEventIds.CmbWaypoint,
    InputControls = new InputControls
    {
        AndroidKeycodes = new[]
        {
            AndroidKeyCode.KEYCODE_SHIFT_LEFT
        },
        MouseActions = new[]
        {
            MouseAction.MouseRightClick
        }
    }
};

경유지 추가 동작이 Shift+right-click에 바인딩된 입력 오버레이 스크린샷

이 섹션에서는 코드 예시에서 호출되는 메서드를 설명합니다.

Kotlin

InputAction.create에는 다음과 같은 매개변수가 있습니다.

  • actionLabel은 이 동작을 나타내는 UI에 표시되는 문자열입니다. 현지화는 자동으로 진행되지 않으므로, 사전에 현지화할지 결정하면 됩니다.
  • uniqueId는 이 동작을 식별하기 위한 정수 ID입니다. 각 동작에는 일관된 고유 식별자가 있어야 합니다. 이 샘플에는 열거형이 사용됩니다. 자세한 내용은 키 ID 추적을 참고하세요.
  • inputControls는 이 동작에 사용된 입력 컨트롤을 정의합니다. 입력 컨트롤은 사용자 인터페이스의 일관된 글리프에 매핑됩니다.

InputControls.create는 동작과 연결된 입력을 만듭니다. 사용할 수 있는 매개변수는 다음과 같습니다.

  • keycodes는 동작과 연결된 키보드 입력을 나타내는 정수 목록입니다. 이는 KeyEvent 클래스에서 정의됩니다.
  • mouseActions는 이 동작과 연결된 마우스 입력을 나타내는 정수 목록입니다. 이는 InputControls 자체에서 정의됩니다.

자바

InputAction.create에는 다음과 같은 매개변수가 있습니다.

  • actionLabel은 이 동작을 나타내는 UI에 표시되는 문자열입니다. 현지화는 자동으로 진행되지 않으므로, 사전에 현지화할지 결정하면 됩니다.
  • uniqueId는 이 동작을 식별하기 위한 정수 ID입니다. 각 동작에는 일관된 고유 식별자가 있어야 합니다. 이 샘플에는 열거형이 사용됩니다. 자세한 내용은 키 ID 추적을 참고하세요.
  • inputControls는 이 동작에 사용된 입력 컨트롤을 정의합니다. 입력 컨트롤은 사용자 인터페이스의 일관된 글리프에 매핑됩니다.

InputControls.create는 동작과 연결된 입력을 만듭니다. 사용할 수 있는 매개변수는 다음과 같습니다.

  • keycodes는 동작과 연결된 키보드 입력을 나타내는 정수 목록입니다. 이는 KeyEvent 클래스에서 정의됩니다.
  • mouseActions는 이 동작과 연결된 마우스 입력을 나타내는 정수 목록입니다. 이는 InputControls 자체에서 정의됩니다.

C#

InputAction에는 다음과 같은 필드가 있습니다.

  • ActionLabel은 이 동작을 나타내는 UI에 표시되는 문자열입니다. 현지화는 자동으로 진행되지 않으므로, 사전에 현지화할지 결정하면 됩니다.
  • UniqueId는 이 동작을 식별하기 위한 정수 ID입니다. 각 동작에는 일관된 고유 식별자가 있어야 합니다. 이 샘플에는 열거형이 사용됩니다. 키 ID 추적을 참고하세요.
  • InputControls는 이 동작에 사용된 입력 컨트롤을 정의합니다. 입력 컨트롤은 사용자 인터페이스의 일관된 글리프에 매핑됩니다.

InputControls는 동작과 연결된 입력을 나타냅니다. 다음과 같은 필드가 있습니다.

  • AndroidKeycodes는 동작과 연결된 키보드 입력을 나타내는 정수 목록입니다. 이는 AndroidKeycode 클래스에서 정의됩니다.
  • MouseActions는 이 동작과 연결된 마우스 입력을 나타내는 MouseAction 값의 목록입니다.

입력 그룹 정의

InputGroup은 유사한 InputAction 객체 그룹입니다. 예를 들면 다음과 같습니다.

  • 메뉴 탐색과 게임 내 이동을 위한 서로 다른 입력 세트를 지정할 수 있습니다.
  • 운전과 걷기 등 게임 내 이동 모드에 따라 서로 다른 입력 세트를 지정할 수 있습니다.
  • 오버월드 탐색 또는 개별 레벨 플레이 등 게임의 현재 상태에 따라 서로 다른 입력 세트를 지정할 수 있습니다.

입력을 그룹으로 구성하면 플레이어가 현재 상황에 맞는 키 결합을 좀 더 쉽게 찾을 수 있습니다.

Kotlin

val movementInputGroup = InputGroup.create(
    "Basic Movement",
    listOf(jumpInputAction, leftInputAction, rightInputAction, useInputAction)
)

자바

InputGroup movementInputGroup = InputGroup.create(
        "Basic Movement",
        Arrays.asList(jumpInputAction, leftInputAction, rightInputAction, useInputAction)
);

C#

var movementInputGroup = new InputGroup
{
    GroupLabel = "Basic Movement",
    InputActions = new List<InputAction>
    {
        jumpInputAction,
        leftInputAction,
        rightInputAction,
        useInputAction
    }
}

이 섹션에서는 코드 예시에서 사용된 메서드 호출을 설명합니다.

Kotlin

InputGroup.create에는 다음과 같은 매개변수가 있습니다.

  • groupLabel은 동작 세트를 논리적으로 그룹화하는 데 사용할 수 있는 UI에 표시되는 문자열입니다. 이 문자열은 자동으로 현지화되지 않습니다.
  • inputActions는 마지막 단계에서 정의한 InputAction 객체의 목록입니다. 이러한 모든 동작은 이 그룹의 제목 아래에 시각적으로 표시됩니다.

자바

InputGroup.create에는 다음과 같은 매개변수가 있습니다.

  • groupLabel은 동작 세트를 논리적으로 그룹화하는 데 사용할 수 있는 UI에 표시되는 문자열입니다. 이 문자열은 자동으로 현지화되지 않습니다.
  • inputActions는 마지막 단계에서 정의한 InputAction 객체의 목록입니다. 이러한 모든 동작은 이 그룹의 제목 아래에 시각적으로 표시됩니다.

C#

InputGroup에는 다음과 같은 필드가 있습니다.

  • GroupLabel은 동작 세트를 논리적으로 그룹화하는 데 사용할 수 있는 UI에 표시되는 문자열입니다. 이 문자열은 자동으로 현지화되지 않습니다.
  • InputActions는 마지막 단계에서 정의한 InputAction 객체의 목록입니다. 이러한 모든 동작은 이 그룹의 제목 아래에 시각적으로 표시됩니다.

입력 맵 빌드

InputMap은 게임에서 사용할 수 있는 모든 InputGroup 객체의 모음이므로 플레이어가 실행할 것으로 예상할 수 있는 모든 InputAction 객체입니다.

다음 예시에서 MovementInputGroup 객체는 MouseSettings 객체와 그룹화됩니다. MouseSettings 객체는 마우스 민감도를 조정할 수 있고 마우스가 y축에서 반전되어 있음을 나타냅니다.

Kotlin

return InputMap.create(
    listOf(movementInputGroup, specialInputGroup),
    MouseSettings.create(true, true)
)

자바

return InputMap.create(
        Arrays.asList(movementInputGroup, specialInputGroup),
        MouseSettings.create(true, true)
);

C#

return new InputMap
{
    InputGroups = new List<InputGroup> {movementInputGroup, specialInputGroup},
    MouseSettings = new MouseSettings
    {
        AllowMouseSensitivityAdjustment = true,
        InvertMouseMovement = true
    }
}

입력 맵 제출

유효한 InputMap을 반환하는 게임에 InputMapProvider가 작성되고 나면 입력 SDK에 등록해야 합니다. 게임의 입력이 변경되지 않는 경우에는 게임 전체 기간 동안 한 번만 등록하면 됩니다. InputMapProvider가 Android 수명 주기 이벤트의 영향을 받지 않기 때문입니다.

Kotlin

private val myInputMapProvider by lazy {
    MyInputMapProvider()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val inputMappingClient = Input.getInputMappingClient(this)
    inputMappingClient.registerInputMappingProvider(myInputMapProvider)
}

자바

private final MyInputMapProvider myInputMapProvider = new MyInputMapProvider();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    InputMappingClient inputMappingClient = Input.getInputMappingClient(this);
    inputMappingClient.registerInputMappingProvider(myInputMapProvider);
}

C#

public void Start() {
    InputMappingClient inputMappingClient = Input.GetInputMappingClient();
    inputMappingClient.registerInputMappingProvider(myInputMapProvider);
}

게임이 완료되면 입력 매핑 제공자를 등록 취소해야 합니다. 취소하지 않아도 SDK는 리소스 유출을 방지할 만큼 지능적입니다.

Kotlin

override fun onDestroy() {
    val inputMappingClient = Input.getInputMappingClient(this)
    inputMappingClient.unregisterInputMappingProvider(myInputMapProvider)

    super.onDestroy()
}

자바

@Override
protected void onDestroy() {
    InputMappingClient inputMappingClient = Input.getInputMappingClient(this);
    inputMappingClient.unregisterInputMappingProvider(myInputMapProvider);

    super.onDestroy();
}

C#

public void OnDestroy() {
    InputMappingClient inputMappingClient = Input.GetInputMappingClient();
    inputMappingClient.unregisterInputMappingProvider(myInputMapProvider);
}

키 ID 추적

정의한 각 InputAction의 고유 ID를 추적해야 합니다. 다음 열거형에서는 이 주제에 있는 모든 샘플의 고유 ID를 추적합니다. ID는 키 변경사항을 추적하는 데 사용되므로 현지화된 동작 이름 해시는 사용하지 마세요.

Kotlin

enum class InputEventIds(val id: Int) {
    JUMP(0),
    LEFT(1),
    RIGHT(2),
    USE(3),
    SPECIAL_JUMP(4),
    SPECIAL_DUCK(5),
}

자바

public enum InputEventIds {
    JUMP,
    LEFT,
    RIGHT,
    USE,
    SPECIAL_JUMP,
    SPECIAL_DUCK
}

C#

public enum InputEventIds
{
    JUMP,
    LEFT,
    RIGHT,
    USE,
    SPECIAL_JUMP,
    SPECIAL_DUCK
}

테스트

입력 SDK가 제대로 구현되었는지 테스트하는 방법에는 두 가지가 있습니다. Google Play 게임즈 UI에서 열어 플레이어에게 표시되는 내용을 확인하거나 자동 테스트 및 확인을 위해 adb shell에서 여는 방법입니다.

사용자 인터페이스

Google Play 게임즈 UI에서 테스트하려면 Shift+Tab을 눌러 게임 대시보드를 엽니다. 대시보드에서 Controls를 클릭하여 현재 바인딩된 컨트롤 목록을 확인합니다.

위에서 설명한 흐름을 보여주는 이미지 Shift+Tab을 누르면 게임 대시보드가 열립니다. 그런 다음 &#39;컨트롤&#39;을 클릭하면 컨트롤 오버레이가 열립니다. 이 오버레이에는 &#39;Basic Movement&#39;라는 그룹이 표시되며 그 안에 &#39;Jump&#39;, &#39;Left&#39;, &#39;Right&#39;가 표시됩니다. 각 컨트롤에는 해당 작업을 실행하는 컨트롤이 표시됩니다. 예를 들어 &#39;Jump&#39;는 아래에 &#39;Key W + Key Up&#39;이라고 쓰여있고 오른쪽에 &#39;w&#39; 키와 &#39;up&#39; 키가 있는 큰 이미지가 있습니다. &#39;Duck&#39;이라고 쓰여진 &#39;Special Input&#39;이라는 섹션도 있습니다.

명령줄

입력은 명령줄에서 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
}

키 결합 변경사항 동기화

많은 게임에서 플레이어는 키 결합을 맞춤설정할 수 있습니다. 따라서 InputMapProvider에 반환하는 데이터가 플레이어의 현재 설정에 맞게 최신 상태인지 확인해야 합니다. 필요한 경우 플레이어가 입력 체계 변경을 완료할 때마다 최신 입력 맵으로 registerInputMappingProvider를 안전하게 호출할 수 있습니다.

현지화

입력 SDK는 Android의 현지화 시스템을 사용하지 않습니다. 따라서 InputMap을 제출할 때 현지화된 문자열을 제공해야 합니다. 하지만 이렇게 하면 게임 엔진의 현지화 시스템을 사용할 수도 있습니다.

다음 단계

입력 SDK를 게임에 통합한 후에도 남은 Google Play 게임즈 요구사항을 계속 진행할 수 있습니다. 자세한 내용은 Google Play 게임즈 시작하기를 참고하세요.