Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Controles, gamepads y joysticks

Godot admite cientos de modelos de controles gracias a la comunidad SDL game controller database.

Los controles son compatibles con Windows, macOS, Linux, Android, iOS y HTML5.

Ten en cuenta que dispositivos más especializados como volantes, pedales de timón y HOTAS (Hands-On Throttle and Stick) son menos probados y es posible que no siempre funcionen como se espera. La capacidad de anular la retroalimentación de fuerza para esos dispositivos aún no está implementada. Si tienes acceso a alguno de esos dispositivos, no dudes en informar errores en GitHub.

En esta guía aprenderás:

  • Cómo escribir su lógica de entrada para admitir entradas de teclado y de controles.

  • Cómo los controles pueden comportarse de manera diferente a la entrada del teclado/mouse.

  • Solución de problemas con los controles en Godot.

Soporte para entrada universal

Gracias al sistema de acción de entrada de Godot, hace posible admitir la entrada tanto del teclado como del control sin tener que escribir rutas de código separadas. En lugar de codificar las teclas o los botones del control en sus scripts, debe crear acciones de entrada en la Configuración del Proyecto, que luego se referirán a las entradas de clave y control especificadas.

Las acciones de entrada se explican en detalle en la página Usando InputEvent.

Nota

A diferencia de la entrada del teclado, admitir la entrada del mouse y del control para una acción (como mirar alrededor en un juego en primera persona) requerirá diferentes rutas de código, ya que deben manejarse por separado.

¿Qué método de entrada singleton debo usar?

Hay 3 formas de obtener entrada de forma analógica:

  • Cuando tenga dos ejes (como un joystick o movimiento WASD) y desee que ambos ejes se comporten como una sola entrada, use 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)
  • Cuando tiene un eje que puede ir en ambos sentidos (como un acelerador en una palanca de vuelo), o cuando desea manejar ejes separados individualmente, use 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")
  • Para otros tipos de entrada analógica, como manejar un disparador o manejar una dirección a la vez, use Input.get_action_strength():

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

Para entradas digitales/booleanas no analógicas (sólo valores "presionados" o "no presionados"), como botones del control, botones del mouse o teclas del teclado, use Input.is_action_pressed():

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

Nota

If you need to know whether an input was just pressed in the previous frame, use Input.is_action_just_pressed() instead of Input.is_action_pressed(). Unlike Input.is_action_pressed() which returns true as long as the input is held, Input.is_action_just_pressed() will only return true for one frame after the button has been pressed.

En las versiones de Godot anteriores a 3.4, como 3.3, Input.get_vector() y Input.get_axis() no están disponibles. Sólo Input.get_action_strength() y Input.is_action_pressed() están disponibles en Godot 3.3.

Vibration

Vibration (also called haptic feedback) can be used to enhance the feel of a game. For instance, in a racing game, you can convey the surface the car is currently driving on through vibration, or create a sudden vibration on a crash.

Use the Input singleton's start_joy_vibration method to start vibrating a gamepad. Use stop_joy_vibration to stop vibration early (useful if no duration was specified when starting).

On mobile devices, you can also use vibrate_handheld to vibrate the device itself (independently from the gamepad). On Android, this requires the VIBRATE permission to be enabled in the Android export preset before exporting the project.

Nota

Vibration can be uncomfortable for certain players. Make sure to provide an in-game slider to disable vibration or reduce its intensity.

Diferencias entre teclado/mouse y entrada del controlador

Si está acostumbrado a manejar la entrada del teclado y el mouse, es posible que se sorprenda de cómo los controles manejan situaciones específicas.

Zona muerta

A diferencia de los teclados y ratones, los controles ofrecen ejes con entradas analógicas. La ventaja de las entradas analógicas es que ofrecen flexibilidad adicional para las acciones. A diferencia de las entradas digitales que sólo pueden proporcionar potencias de 0.0 y 1.0, una entrada analógica puede proporcionar cualquier intensidad entre 0.0 y 1.0. La desventaja es que sin un sistema de zona muerta, la fuerza de un eje analógico nunca será igual a 0.0 debido a cómo está construido físicamente el control. En cambio, permanecerá en un valor bajo como 0.062. Este fenómeno se conoce como drifting y puede ser más notorio en controles viejos o defectuosos.

Tomemos un juego de carreras como ejemplo del mundo real. Gracias a las entradas analógicas, podemos conducir el coche lentamente en una dirección u otra. Sin embargo, sin un sistema de zona muerta, el automóvil se conduciría lentamente por sí mismo incluso si el jugador no está tocando el joystick. Esto se debe a que la fuerza del eje direccional no será igual a 0.0 cuando lo esperamos. Como no queremos que nuestro coche se dirija sólo en este caso, definimos un valor de "zona muerta" de 0.2 que ignorará todas las entradas cuya fuerza sea inferior a 0.2. Un valor de zona muerta ideal es lo suficientemente alto como para ignorar la entrada causada por la deriva del joystick, pero es lo suficientemente bajo como para no ignorar la entrada real del jugador.

Godot features a built-in deadzone system to tackle this problem. The default value is 0.5, but you can adjust it on a per-action basis in the Project Settings' Input Map tab. For Input.get_vector(), the deadzone can be specified as an optional 5th parameter. If not specified, it will calculate the average deadzone value from all of the actions in the vector.

Eventos de "eco"

A diferencia de la entrada de teclado, mantener presionado un botón del control, como la dirección del D-pad, no generará eventos de entrada repetidos a intervalos fijos (también conocidos como eventos de "eco"). Esto se debe a que, en primer lugar, el sistema operativo nunca envía eventos de "eco" para la entrada del control.

Si desea que los botones del control envíen eventos de eco, tendrá que generar InputEvent objetos por código y analizarlo usando Input.parse_input_event() en intervalos regulares. Esto se puede lograr con la ayuda de un nodo Timer.

Window focus

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

While this is useful for third-party split screen functionality, it can also have adverse effects. Players may accidentally send controller inputs to the running project while interacting with another window.

If you wish to ignore events when the project window isn't focused, you will need to create an autoload called Focus with the following script and use it to check all your inputs:

# Focus.gd
extends Node

var focused := true

func _notification(what: int) -> void:
    match what:
        NOTIFICATION_APPLICATION_FOCUS_OUT:
            focused = false
        NOTIFICATION_APPLICATION_FOCUS_IN:
            focused = true


func input_is_action_pressed(action: StringName) -> bool:
    if focused:
        return Input.is_action_pressed(action)

    return false


func event_is_action_pressed(event: InputEvent, action: StringName) -> bool:
    if focused:
        return event.is_action_pressed(action)

    return false

Then, instead of using Input.is_action_pressed(action), use Focus.input_is_action_pressed(action) where action is the name of the input action. Also, instead of using event.is_action_pressed(action), use Focus.event_is_action_pressed(event, action) where event is an InputEvent reference and action is the name of the input action.

Power saving prevention

Unlike keyboard and mouse input, controller inputs do not inhibit sleep and power saving measures (such as turning off the screen after a certain amount of time has passed).

To combat this, Godot enables power saving prevention by default when a project is running. If you notice the system is turning off its display when playing with a gamepad, check the value of Display > Window > Energy Saving > Keep Screen On in the Project Settings.

On Linux, power saving prevention requires the engine to be able to use D-Bus. Check whether D-Bus is installed and reachable if running the project within a Flatpak, as sandboxing restrictions may make this impossible by default.

Solución De Problemas

Ver también

Puedes ver una lista de problemas conocidos con el soporte de controladores en GitHub.

Mi control no es reconocido por Godot.

Primero, revisa que tu control es detectado por otras aplicaciones. Puedes usar el sitio web Gamepad Tester para confirmar que tu control es detectado.

On Windows Godot only supports up to 4 controllers at a time. This is because Godot uses the XInput API, which is limited to supporting 4 controllers at once. Additional controllers above this limit are ignored by Godot.

Mi control tiene botones o ejes asignados incorrectamente.

First, if your controller provides some kind of firmware update utility, make sure to run it to get the latest fixes from the manufacturer. For instance, Xbox One and Xbox Series controllers can have their firmware updated using the Xbox Accessories app. (This application only runs on Windows, so you have to use a Windows machine or a Windows virtual machine with USB support to update the controller's firmware.) After updating the controller's firmware, unpair the controller and pair it again with your PC if you are using the controller in wireless mode.

Si los botones se asignan incorrectamente, esto puede deberse a una asignación errónea del SDL game controller database. Puede contribuir con un mapeo actualizado para que se incluya en la próxima versión de Godot abriendo un pull request en el repositorio vinculado.

Hay muchas formas de crear asignaciones. Una opción es utilizar el asistente de mapeo en el official Joypads demo. Una vez que tenga un mapeo funcional para su control, puede probarlo definiendo la variable de entorno SDL_GAMECONTROLLERCONFIG antes de ejecutar Godot:

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

Para probar asignaciones en plataformas que no son de escritorio o para distribuir su proyecto con asignaciones de controles adicionales, puede agregarlas llamando a : ref: Input.add_joy_mapping() tan pronto como sea posible en la función del script _ready().

Mi control funciona en una plataforma determinada, pero no en otra plataforma.

Linux

If you're using a self-compiled engine binary, make sure it was compiled with udev support. This is enabled by default, but it is possible to disable udev support by specifying udev=no on the SCons command line. If you're using an engine binary supplied by a Linux distribution, double-check whether it was compiled with udev support.

Controllers can still work without udev support, but it is less reliable as regular polling must be used to check for controllers being connected or disconnected during gameplay (hotplugging).

HTML5

El soporte del control de HTML5 es a menudo menos confiable en comparación con las plataformas "nativas". La calidad de la compatibilidad con el control tiende a variar enormemente entre los navegadores. Como resultado, es posible que deba indicar a sus jugadores que usen un navegador diferente si no pueden hacer que su control funcione.