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.

컨트롤러, 게임패드, 조이스틱

Godot는 기본적으로 수백 가지 컨트롤러 모델을 지원합니다. 컨트롤러는 Windows, macOS, Linux, Android, iOS 및 웹에서 지원됩니다.

참고

Godot 4.5부터 엔진은 Windows, macOS 및 Linux에서의 컨트롤러 지원을 위해 `SDL 3 <https://www.libsdl.org/index.php>`__을 사용합니다. 이는 지원되는 컨트롤러 목록과 해당 동작이 SDL 3을 사용하는 다른 게임 및 엔진에서 사용할 수 있는 것과 거의 일치해야 함을 의미합니다. SDL은 창 작업이나 사운드가 아닌 입력에만 사용된다는 점에 유의하세요.

Prior to Godot 4.5, the engine used its own controller support code. This can cause certain controllers to behave incorrectly. This custom code is still used to support controllers on Android and Web, so it may result in issues appearing only on those platforms.

스티어링 휠, 방향타 페달 및 `HOTAS <https://en.wikipedia.org/wiki/HOTAS>`__과 같은 보다 특수화된 장치는 테스트를 덜 거쳐 항상 예상대로 작동하지 않을 수 있습니다. 해당 장치에 대한 강제 피드백 재정의도 아직 구현되지 않았습니다. 해당 장치 중 하나에 액세스할 수 있는 경우 주저하지 말고 `GitHub <https://github.com/godotengine/godot/blob/master/CONTRIBUTING.md#reporting-bugs>`__에서 버그를 보고하세요.

이 가이드에서 다음 내용을 배울 것입니다:

  • 키보드와 컨트롤러 입력을 모두 지원하도록 입력 로직을 작성하는 방법.

  • 컨트롤러가 키보드/마우스 입력과 어떻게 다르게 작동할 수 있는지.

  • Godot의 컨트롤러 문제를 해결합니다.

유니버설 Windows 플랫폼으로 내보내기

Godot의 입력 작업 시스템 덕분에 Godot는 별도의 코드 경로를 작성하지 않고도 키보드와 컨트롤러 입력을 모두 지원할 수 있습니다. 스크립트에 키나 컨트롤러 버튼을 하드코딩하는 대신 프로젝트 설정에 *입력 작업*을 생성해야 합니다. 그러면 지정된 키와 컨트롤러 입력을 참조하게 됩니다.

입력 동작은 InputEvent 사용하기 페이지에 자세히 설명되어 있습니다.

참고

키보드 입력과 달리 작업(예: 1인칭 게임에서 둘러보기)에 대한 마우스 및 컨트롤러 입력을 모두 지원하려면 별도로 처리해야 하므로 다른 코드 경로가 필요합니다.

어떤 이동 메서드를 사용해야 할까요?

아날로그 인식 방식으로 입력을 얻는 방법에는 3가지가 있습니다.

  • 두 개의 축(예: 조이스틱 또는 WASD 이동)이 있고 두 축이 단일 입력으로 작동하도록 하려면 ``Input.get_vector()``를 사용하세요.

# `velocity` will be a Vector2 between `Vector2(-1.0, -1.0)` and `Vector2(1.0, 1.0)`.
# This handles deadzone in a correct way for most use cases.
# The resulting deadzone will have a circular shape as it generally should.
var velocity = Input.get_vector("move_left", "move_right", "move_forward", "move_back")

# The line below is similar to `get_vector()`, except that it handles
# the deadzone in a less optimal way. The resulting deadzone will have
# a square-ish shape when it should ideally have a circular shape.
var velocity = Vector2(
        Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
        Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
).limit_length(1.0)
  • 양방향으로 이동할 수 있는 축이 하나 있거나(예: 비행 스틱의 스로틀) 별도의 축을 개별적으로 처리하려는 경우 ``Input.get_axis()``를 사용하세요.

# `walk` will be a floating-point number between `-1.0` and `1.0`.
var walk = Input.get_axis("move_left", "move_right")

# The line above is a shorter form of:
var walk = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
  • 트리거 처리 또는 한 번에 한 방향 처리와 같은 다른 유형의 아날로그 입력의 경우 ``Input.get_action_strength()``를 사용합니다.

# `strength` will be a floating-point number between `0.0` and `1.0`.
var strength = Input.get_action_strength("accelerate")

컨트롤러 버튼, 마우스 버튼 또는 키보드 키와 같은 아날로그가 아닌 디지털/부울 입력("눌렸음" 또는 "누르지 않음" 값만 해당)의 경우 ``Input.is_action_pressed()``를 사용합니다.

# `jumping` will be a boolean with a value of `true` or `false`.
var jumping = Input.is_action_pressed("jump")

참고

이전 프레임에서 입력이 그냥 눌렸는지 확인해야 하는 경우 Input.is_action_pressed() 대신 ``Input.is_action_just_pressed()``를 사용하세요. 입력이 유지되는 동안 ``true``를 반환하는 ``Input.is_action_pressed()``와 달리 ``Input.is_action_just_pressed()``는 버튼을 누른 후 한 프레임 동안만 ``true``를 반환합니다.

빼기

진동(*햅틱 피드백*이라고도 함)을 사용하여 게임의 느낌을 향상시킬 수 있습니다. 예를 들어, 레이싱 게임에서는 진동을 통해 자동차가 현재 주행 중인 표면을 전달할 수도 있고, 충돌 시 갑작스러운 진동을 생성할 수도 있습니다.

입력 싱글톤의 start_joy_vibration 메서드를 사용하여 게임패드 진동을 시작합니다. 진동을 조기에 중지하려면 :ref:`stop_joy_vibration<class_Input_method_stop_joy_vibration>`를 사용하십시오(시작할 때 지속 시간을 지정하지 않은 경우 유용함).

모바일 장치에서는 vibrate_handheld<class_Input_method_vibrate_handheld>`를 사용하여 장치 자체를 진동시킬 수도 있습니다(게임패드와는 별도로). Android에서는 프로젝트를 내보내기 전에 Android 내보내기 사전 설정에서 ``VIBRATE` 권한을 활성화해야 합니다.

참고

특정 플레이어에게는 진동이 불편할 수 있습니다. 진동을 비활성화하거나 강도를 낮추려면 게임 내 슬라이더를 제공하십시오.

키보드/마우스와 컨트롤러 입력의 차이점

키보드 및 마우스 입력을 처리하는 데 익숙하다면 컨트롤러가 특정 상황을 처리하는 방식에 놀랄 수 있습니다.

데드존

키보드 및 마우스와 달리 컨트롤러는 아날로그 입력이 있는 축을 제공합니다. 아날로그 입력의 장점은 작업에 추가적인 유연성을 제공한다는 것입니다. 0.01.0``의 강도만 제공할 있는 디지털 입력과 달리 아날로그 입력은 ``0.01.0 사이의 모든 강도를 제공할 수 있습니다. 단점은 데드존 시스템이 없으면 컨트롤러가 물리적으로 구축된 방식으로 인해 아날로그 축의 강도가 ``0.0``와 결코 같지 않다는 것입니다. 대신 ``0.062``와 같은 낮은 값에 유지됩니다. 이 현상은 *드리프트*라고 알려져 있으며 오래되었거나 결함이 있는 컨트롤러에서 더 눈에 띄게 나타날 수 있습니다.

실제 사례로 레이싱 게임을 살펴보겠습니다. 아날로그 입력 덕분에 자동차를 한 방향이나 다른 방향으로 천천히 조종할 수 있습니다. 그러나 데드존 시스템이 없으면 플레이어가 조이스틱을 건드리지 않아도 자동차는 스스로 천천히 조종하게 됩니다. 이는 방향 축 강도가 예상할 때 ``0.0``와 같지 않기 때문입니다. 이 경우 자동차가 스스로 조종하는 것을 원하지 않기 때문에 ``0.2``보다 강도가 낮은 모든 입력을 무시하는 ``0.2``의 "데드 존" 값을 정의합니다. 이상적인 데드존 값은 조이스틱 드리프트로 인한 입력을 무시할 만큼 높지만 플레이어의 실제 입력을 무시하지 않을 만큼 낮습니다.

Godot는 이 문제를 해결하기 위해 내장된 데드존 시스템을 갖추고 있습니다. 기본값은 ``0.5``이지만 프로젝트 설정' 입력 맵 탭에서 작업별로 조정할 수 있습니다. ``Input.get_vector()``의 경우 데드존을 선택적 5번째 매개변수로 지정할 수 있습니다. 지정하지 않으면 벡터의 모든 동작에서 평균 데드존 값을 계산합니다.

"에코" 이벤트

키보드 입력과 달리 D패드 방향과 같은 컨트롤러 버튼을 누르고 있으면 고정된 간격으로 반복되는 입력 이벤트('에코' 이벤트라고도 함)가 발생하지 않습니다. 이는 운영 체제가 애초에 컨트롤러 입력에 대해 "에코" 이벤트를 보내지 않기 때문입니다.

컨트롤러 버튼이 에코 이벤트를 보내도록 하려면 코드로 InputEvent 개체를 생성하고 Input.parse_input_event() <class_Input_method_parse_input_event>`을 사용하여 정기적으로 구문 분석해야 합니다. 이는 :ref:`class_Timer 노드의 도움으로 수행될 수 있습니다.

Windows

Unlike keyboard input, controller inputs can by default be seen by all windows on the operating system, including unfocused windows.

이는 `타사 분할 화면 기능 <https://nucleus-coop.github.io/>`__에 유용하지만 부작용이 있을 수도 있습니다. 플레이어가 다른 창과 상호 작용하는 동안 실수로 실행 중인 프로젝트에 컨트롤러 입력을 보낼 수 있습니다.

If you wish to ignore controller input events when the project isn't focused, set ProjectSettings.input_devices/joypads/ignore_joypad_on_unfocused_application to true. Alternatively, you can also set Input.ignore_joypad_on_unfocused_application to true.

절전 방지

키보드 및 마우스 입력과 달리 컨트롤러 입력은 절전 및 절전 조치(예: 일정 시간이 지난 후 화면 끄기)를 방해하지 않습니다.

이 문제를 해결하기 위해 Godot는 프로젝트가 실행 중일 때 기본적으로 절전 방지를 활성화합니다. 게임패드로 플레이할 때 시스템의 디스플레이가 꺼지는 경우 프로젝트 설정에서 디스플레이 > 창 > 에너지 절약 > 화면 켜기 유지 값을 확인하세요.

문제 해결

더 보기

Github에서 열린 HTML5 이슈 목록을 확인해서 관심있는 기능에 아직 이슈가 있는지 찾아보세요. 기능이 아직 없다면 하나를 열어서 관심있는 기능을 이야기를 해보세요.

내 컨트롤러가 Godot에서 인식되지 않습니다.

먼저 다른 응용 프로그램에서 컨트롤러를 인식하는지 확인하세요. Gamepad Tester 웹사이트를 사용하여 컨트롤러가 인식되는지 확인할 수 있습니다.

Windows에서 Godot는 한 번에 최대 4개의 컨트롤러만 지원합니다. 이는 Godot가 XInput API를 사용하기 때문에 한 번에 4개의 컨트롤러를 지원하도록 제한되어 있습니다. 이 제한을 초과하는 추가 컨트롤러는 Godot에 의해 무시됩니다.

내 컨트롤러에 버튼이나 축이 잘못 매핑되어 있습니다.

첫째, 컨트롤러가 일종의 펌웨어 업데이트 유틸리티를 제공하는 경우 이를 실행하여 제조업체로부터 최신 수정 사항을 받으십시오. 예를 들어 Xbox One 및 Xbox 시리즈 컨트롤러는 `Xbox 액세서리 앱 <https://www.microsoft.com/en-us/p/xbox-accessories/9nblggh30xj3>`__을 사용하여 펌웨어를 업데이트할 수 있습니다. (이 애플리케이션은 Windows에서만 실행되므로 컨트롤러의 펌웨어를 업데이트하려면 Windows 머신이나 USB를 지원하는 Windows 가상 머신을 사용해야 합니다.) 컨트롤러의 펌웨어를 업데이트한 후 컨트롤러를 무선 모드로 사용하는 경우 컨트롤러의 페어링을 해제하고 PC와 다시 페어링하십시오.

버튼이 잘못 매핑된 경우 이는 Godot에서 사용하는 SDL 게임 컨트롤러 데이터베이스 또는 `Godot 게임 컨트롤러 데이터베이스 <https://github.com/godotengine/godot/blob/master/core/input/godotcontrollerdb.txt>`__의 잘못된 매핑 때문일 수 있습니다. 이 경우 컨트롤러에 대한 사용자 정의 매핑을 생성해야 합니다.

There are many ways to create mappings. One option is to start Steam in Big Picture mode, configure the controller and then look in config/config.vdf in the Steam installation directory for the SDL_GamepadBind entry. Another option is to use SDL's testcontroller application (the link only provides a Windows executable). Once you have a working mapping for your controller, you can test it by defining the SDL_GAMECONTROLLERCONFIG environment variable before running Godot:

export SDL_GAMECONTROLLERCONFIG="your:mapping:here"
./path/to/godot.x86_64

Once you are satisfied with the custom mapping, you can contribute it for the next Godot version by opening a pull request on the Godot game controller database, or creating an issue in the Godot repository.

Since Godot uses SDL 3 for controller input, please consider contributing the mapping for the SDL library as well by opening a pull request on the official SDL gamepad database, or creating an issue in the SDL repository.

참고

Note that there are "generic" controllers on the market (usually their Input.get_joy_info(device)["raw_name"] property contains "USB Gamepad" string), and different generic controllers may use the same chipset, but they would have a different button placement, so creating a mapping for one of those controllers will most likely conflict with other ones, because the engine has no way of differentiating between controllers with the same chipset.

내 컨트롤러는 특정 플랫폼에서는 작동하지만 다른 플랫폼에서는 작동하지 않습니다.

Linux

자체 컴파일된 엔진 바이너리를 사용하는 경우 udev 지원으로 컴파일되었는지 확인하세요. 이는 기본적으로 활성화되어 있지만 SCons 명령줄에 ``udev=no``를 지정하여 udev 지원을 비활성화할 수 있습니다. Linux 배포판에서 제공하는 엔진 바이너리를 사용하는 경우 udev 지원으로 컴파일되었는지 다시 확인하세요.

컨트롤러는 udev 지원 없이도 계속 작동할 수 있지만 게임 플레이 중에 컨트롤러가 연결되거나 연결 해제되었는지 확인하려면 정기적인 폴링을 사용해야 하기 때문에 안정성이 떨어집니다(핫 플러그).

Android

페이지 상단에 설명된 대로 모바일 플랫폼의 컨트롤러 지원은 입력을 위해 SDL을 사용하는 대신 사용자 정의 구현에 의존합니다. 이는 컨트롤러 지원이 데스크톱 플랫폼보다 안정성이 떨어질 수 있음을 의미합니다.

Support for SDL-based controller input on mobile platforms is planned in a future release.

웹 컨트롤러 지원은 "네이티브" 플랫폼에 비해 안정성이 떨어지는 경우가 많습니다. 컨트롤러 지원 품질은 브라우저에 따라 크게 달라지는 경향이 있습니다. 따라서 컨트롤러가 작동하지 않는 경우 플레이어에게 다른 브라우저를 사용하도록 지시해야 할 수도 있습니다.

Like for mobile platforms, support for SDL-based controller input on the web platform is planned in a future release.