Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

InputEvent 사용하기

그것은 무엇입니까?

입력을 관리하는 것은 보통 OS나 플랫폼과 상관없이 복잡합니다. 이것을 조금이나마 쉽게 하기 위해 특수 내장 유형 InputEvent이 제공됩니다. 이 데이터 타입은 여러 타입의 입력 이벤트를 포함하도록 구성할 수 있습니다. 입력 이벤트는 엔진을 통해 이동하고 목적에 따라 여러 위치에서 수신될 수 있습니다.

다음은 Esc 키를 누르면 게임을 종료하는 간단한 예입니다.

func _unhandled_input(event):
    if event is InputEventKey:
        if event.pressed and event.keycode == KEY_ESCAPE:
            get_tree().quit()

그러나 입력 작업을 정의하고 다른 키를 할당할 수 있는 제공된 InputMap 기능을 사용하는 것이 더 깔끔하고 유연합니다. 이렇게 하면 동일한 작업에 대해 여러 키를 정의할 수 있습니다(예: 키보드 Esc 키 및 게임 패드의 시작 버튼). 그런 다음 코드를 업데이트하지 않고도 프로젝트 설정에서 이 매핑을 더 쉽게 변경할 수 있으며, 그 위에 키 매핑 기능을 구축하여 게임이 런타임에 키 매핑을 변경할 수 있도록 할 수도 있습니다!

**프로젝트 > 프로젝트 설정 > 입력 맵**에서 InputMap을 설정한 후 다음과 같은 작업을 사용할 수 있습니다.

func _process(delta):
    if Input.is_action_pressed("ui_right"):
        # Move right.

어떻게 작동하나요?

모든 입력 이벤트는 사용자/플레이어에서 시작됩니다(InputEvent를 생성하여 엔진에 다시 공급할 수 있으므로 제스처에 유용함). 각 플랫폼의 DisplayServer는 운영 체제에서 이벤트를 읽은 다음 이를 루트 :ref:`Window <class_Window>`에 공급합니다.

창의 :ref:`뷰포트 <class_Viewport>`는 수신된 입력에 대해 순서대로 많은 작업을 수행합니다.

../../_images/input_event_flow.webp
  1. 뷰포트가 Windows를 내장하는 경우 뷰포트는 해당 기능에서 이벤트를 창 관리자(예: Windows 크기 조정 또는 이동)로 해석하려고 시도합니다.

  2. 다음으로 포함된 창에 초점이 맞춰지면 이벤트가 해당 창으로 전송되어 창의 뷰포트에서 처리된 후 처리된 것으로 처리됩니다. 내장된 Window에 포커스가 없는 경우 현재 뷰포트의 노드에 다음과 같은 순서로 이벤트가 전달됩니다.

  3. 우선, 표준 노드._input() 함수는 이를 재정의하는 모든 노드에서 호출됩니다(입력 처리를 비활성화하지 않았습니다). 노드.set_process_input()). 함수가 이벤트를 소비하는 경우 :ref:`뷰포트.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`를 호출할 수 있으며 이벤트는 더 이상 확산되지 않습니다. 이를 통해 GUI 이전에도 관심 있는 모든 이벤트를 필터링할 수 있습니다. 게임플레이 입력의 경우 :ref:`노드._unhandled_input() <class_Node_private_method__unhandled_input>`이 일반적으로 더 적합합니다. 이를 통해 GUI가 이벤트를 가로챌 수 있기 때문입니다.

  4. 둘째, GUI에 입력을 제공하고 이를 수신할 수 있는 컨트롤이 있는지 확인합니다. 그렇다면 Control 속성을 사용하여 Control 콜백을 통해 마우스 이벤트에 대한 알림을 받을지 여부와 이러한 이벤트가 추가로 전파되는지 여부를 제어합니다.

  5. 지금까지 아무도 이벤트를 소비하지 않은 경우 노드._shortcut_input() 콜백이 재정의되면 호출됩니다(다음으로 비활성화되지 않음). 노드.set_process_shortcut_input()). 이는 InputEventKey, InputEventShortcut 및 :ref:`InputEventJoypadButton <class_InputEventJoypadButton>`에 대해서만 발생합니다. 함수가 이벤트를 소비하는 경우 :ref:`뷰포트.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`를 호출할 수 있으며 이벤트는 더 이상 확산되지 않습니다. 바로가기 입력 콜백은 바로가기로 의도된 이벤트를 처리하는 데 이상적입니다.

  6. 지금까지 아무도 이벤트를 소비하지 않은 경우 노드._unhandled_key_input() 콜백은 재정의되면 호출됩니다(및 비활성화되지 않음). 노드.set_process_unhandled_key_input()). 이는 이벤트가 :ref:`InputEventKey <class_InputEventKey>`인 경우에만 발생합니다. 함수가 이벤트를 소비하는 경우 :ref:`뷰포트.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`를 호출할 수 있으며 이벤트는 더 이상 확산되지 않습니다. 처리되지 않은 키 입력 콜백은 키 이벤트에 이상적입니다.

  7. 지금까지 아무도 이벤트를 소비하지 않은 경우 노드._unhandled_input() 콜백이 재정의되면 호출됩니다(및 비활성화되지 않음). 노드.set_process_unhandled_input()). 함수가 이벤트를 소비하는 경우 :ref:`뷰포트.set_input_as_handled() <class_Viewport_method_set_input_as_handled>`를 호출할 수 있으며 이벤트는 더 이상 확산되지 않습니다. 처리되지 않은 입력 콜백은 전체 화면 게임플레이 이벤트에 이상적이므로 GUI가 활성화되면 수신되지 않습니다.

  8. 지금까지 아무도 이벤트를 원하지 않았고 Object Picking 함수를 호출합니다. 2D 씬의 경우 :ref:`CollisionObject2D._input_event() <class_CollisionObject2D_private_method__input_event>`에서도 개념적으로 동일한 일이 발생합니다.

하위 및 하위 노드에 이벤트를 보낼 때 뷰포트는 다음 그래픽에 표시된 대로 역방향 깊이 우선 순서로 씬 트리 하단의 노드부터 시작하여 루트 노드에서 끝납니다. 이 프로세스에서 제외되는 것은 Windows와 SubViewport입니다.

../../_images/input_event_scene_flow.webp

참고

이 순서는 이벤트 위치 또는 집중된 제어에 따라 다른 메서드를 사용하는 Control._gui_input() 제한 사항에 따라 씬 트리 위로 이동합니다. 그러나 이러한 이벤트는 특정 컨트롤을 대상으로 하기 때문에 대상 컨트롤 노드의 직계 조상만 이벤트를 수신합니다. GUI 키보드 및 조이패드 이벤트는 씬 트리 위로 이동하지 않으며 이를 수신한 컨트롤에 의해서만 처리될 수 있습니다. 그렇지 않으면 :ref:`노드._unhandled_input() <class_Node_private_method__unhandled_input>`을 통해 비GUI 이벤트로 전파됩니다.

뷰포트는 다른 :ref:`SubViewports <class_SubViewport>`에 이벤트를 보내지 않으므로 다음 방법 중 하나를 사용해야 합니다.

  1. 노드._input() 이후 이벤트를 하위 SubViewports.

  2. 개별 요구 사항에 따라 이벤트 전파를 구현합니다.

Godot의 노드 기반 설계에 따라 이를 통해 전문화된 자식 노드가 특정 이벤트를 처리하고 소비할 수 있으며, 조상과 궁극적으로 씬 루트는 필요한 경우 보다 일반화된 동작을 제공할 수 있습니다.

InputEvent 분석

:ref:`InputEvent <class_InputEvent>`은 기본 내장 유형일 뿐이며 아무것도 나타내지 않으며 이벤트 ID(이벤트마다 증가됨), 장치 인덱스 등과 같은 일부 기본 정보만 포함합니다.

아래 표에 설명된 몇 가지 특수한 유형의 InputEvent가 있습니다.

이벤트

설명

InputEvent

빈 입력 이벤트.

InputEventKey

키코드, 유니코드 값 및 수정자를 포함합니다.

InputEventMouseButton

버튼, 수정자 등과 같은 클릭 정보가 포함되어 있습니다.

InputEventMouseMotion

상대 위치, 절대 위치, 속도 등 모션 정보가 포함되어 있습니다.

InputEventJoypadMotion

조이스틱/조이패드 아날로그 축 정보가 포함되어 있습니다.

InputEventJoypadButton

조이스틱/조이패드 버튼 정보가 포함되어 있습니다.

InputEventScreenTouch

멀티터치 프레스/릴리스 정보가 포함되어 있습니다. (모바일 기기에서만 사용 가능)

InputEventScreenDrag

멀티터치 드래그 정보가 포함되어 있습니다. (모바일 기기에서만 사용 가능)

InputEventMagnifyGesture

위치, 요소 및 수정자를 포함합니다.

InputEventPanGesture

위치, 델타 및 수정자를 포함합니다.

Sprite

더 많은 정보

InputEventShortcut

컨테이너 내장 타입

InputEventAction

일반 작업을 포함합니다. 이러한 이벤트는 종종 프로그래머에 의해 피드백으로 생성됩니다. (이에 대해서는 아래에서 자세히 설명)

입력 액션

입력 작업은 0개 이상의 입력 이벤트를 일반적으로 이해되는 제목으로 그룹화한 것입니다(예: 조이패드 왼쪽 입력과 키보드의 왼쪽 화살표 키를 모두 그룹화하는 기본 "ui_left" 작업). InputEvent를 나타낼 필요는 없지만 게임 로직을 프로그래밍할 때 다양한 입력을 추상화하므로 유용합니다.

이것은 다음을 허용합니다:

  • 동일한 코드는 입력이 다른 여러 장치(예: PC의 키보드, 콘솔의 조이패드)에서 작동합니다.

  • 런타임 시 재구성될 입력입니다.

  • 런타임 시 프로그래밍 방식으로 트리거되는 작업입니다.

입력 맵 탭의 프로젝트 설정 메뉴에서 작업을 생성하고 입력 이벤트를 할당할 수 있습니다.

모든 이벤트에는 InputEvent.is_action(), InputEvent.is_pressed()InputEvent.is_echo() 메서드가 있습니다.

또는 게임 코드의 동작을 게임에 다시 제공하는 것이 바람직할 수도 있습니다(이의 좋은 예는 제스처 감지입니다). 입력 싱글톤에는 :ref:`Input.parse_input_event() <class_input_method_parse_input_event>`에 대한 메서드가 있습니다. 일반적으로 다음과 같이 사용합니다.

var ev = InputEventAction.new()
# Set as ui_left, pressed.
ev.action = "ui_left"
ev.pressed = true
# Feedback.
Input.parse_input_event(ev)

더 보기

프로젝트 설정에서 입력 작업을 추가하는 방법에 대한 튜토리얼은 :ref:`doc_first_3d_game_input_actions`를 참조하세요.

입력맵

코드 입력을 사용자 정의하고 다시 매핑하는 것이 필요한 경우가 많습니다. 전체 워크플로가 작업에 의존하는 경우 InputMap 싱글톤는 런타임에 다른 작업을 재할당하거나 생성하는 데 이상적입니다. 이 싱글톤는 저장되지 않으며(수동으로 수정해야 함) 해당 상태는 프로젝트 설정(project.godot)에서 실행됩니다. 따라서 이러한 유형의 동적 시스템은 프로그래머가 가장 적합하다고 생각하는 방식으로 설정을 저장해야 합니다.