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)
// `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.
Vector2 velocity = Input.GetVector("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.
Vector2 velocity = new Vector2(
Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left"),
Input.GetActionStrength("move_back") - Input.GetActionStrength("move_forward")
).LimitLength(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")
// `walk` will be a floating-point number between `-1.0` and `1.0`.
float walk = Input.GetAxis("move_left", "move_right");
// The line above is a shorter form of:
float walk = Input.GetActionStrength("move_right") - Input.GetActionStrength("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")
// `strength` will be a floating-point number between `0.0` and `1.0`.
float strength = Input.GetActionStrength("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")
// `jumping` will be a boolean with a value of `true` or `false`.
bool jumping = Input.IsActionPressed("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 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.