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.
Checking the stable version of the documentation...
Controller, gamepad e joystick
Godot supporta centinaia di modelli di controller pronto all'uso. I controller sono supportati su Windows, macOS, Linux, Android, iOS e Web.
Nota
A partire da Godot 4.5, il motore si basa su SDL 3 per supportare i controller su Windows, macOS e Linux. Ciò significa che l'elenco dei controller supportati e il loro comportamento dovrebbero corrispondere il più possibile a quanto disponibile in altri giochi e motori che utilizzano SDL 3. Si noti che SDL è utilizzato solo per gli input, non per la gestione delle finestre o dell'audio.
Prima di Godot 4.5, il motore utilizzava il proprio codice di supporto per i controller. Questo poteva causare comportamenti insoliti per alcuni controller. Tale codice personalizzato è tuttora utilizzato per supportare i controller su Android, iOS e Web, pertanto potrebbero manifestarsi problemi solo su queste piattaforme.
Tieni presente che i dispositivi più specializzati come volanti, pedali del timone e HOTAS sono meno testati e potrebbero non funzionare sempre come previsto. Anche la possibilità di disattivare il force feedback per questi dispositivi non è ancora implementata. Se hai accesso a uno di questi dispositivi, non esitare a segnalare eventuali bug su GitHub.
In questa guida imparerai:
Come scrivere la logica di input per supportare sia gli input da tastiera sia da controller.
Come i controller possono comportarsi diversamente rispetto agli input da tastiera/mouse.
Risolvere problemi con i controller in Godot.
Supporting universal input
Grazie al sistema di azioni di input di Godot, è possibile supportare sia l'input da tastiera sia da controller senza dover scrivere percorsi di codice separati. Invece di codificare i tasti o pulsanti del controller negli script, è consigliato creare azioni di input nelle Impostazioni del progetto, che faranno poi riferimento agli input specificati da tastiera e da controller.
Le azioni di input sono spiegate in dettaglio nella pagina Utilizzo di InputEvent.
Nota
A differenza dell'input da tastiera, supportare sia gli input da mouse sia da controller per un'azione (come guardarsi intorno in un gioco in prima persona) richiederà percorsi di codice diversi, poiché è necessario gestirli separatamente.
Quale metodo del singleton Input dovrei utilizzare?
Ci sono 3 modi per ottenere un input in maniera analogica:
Quando si hanno due assi (come il movimento del joystick o dei tasti WASD) e si desidera che entrambi gli assi si comportino come un singolo input, utilizzare
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);
Quando si ha un solo asse che può muoversi in entrambe le direzioni (come ad esempio la manetta di un joystick di volo), o quando si desidera gestire assi separati individualmente, utilizzare
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");
Per altri tipi di input analogico, come la gestione di un grilletto o di una direzione alla volta, utilizzare
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");
Per input digitali/booleani non analogici (solo valori "premuto" o "non premuto"), come i pulsanti del controller, i pulsanti del mouse o i tasti della tastiera, utilizzare 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
Se bisogna sapere se un input è stato appena premuto nel frame precedente, usare Input.is_action_just_pressed() invece di Input.is_action_pressed(). A differenza di Input.is_action_pressed() che restituisce true fin quando l'input viene tenuto premuto, Input.is_action_just_pressed() restituirà true solo per un frame dopo che il pulsante è stato premuto.
Vibrazione
La vibrazione (chiamata anche feedback aptico) può servire per migliorare la sensazione di un gioco. Ad esempio, in un gioco di corse, è possibile trasmettere la superficie su cui l'auto sta viaggiando tramite vibrazioni, oppure creare una vibrazione improvvisa in caso di incidente.
Utilizzare il metodo start_joy_vibration del singleton Input per avviare la vibrazione di un gamepad. Utilizzare il metodo stop_joy_vibration per interrompere la vibrazione prima del previsto (utile se nessuna durata è stata specificata all'avvio).
Sui dispositivi mobili, è possibile utilizzare anche vibrate_handheld per far vibrare il dispositivo stesso (indipendentemente dal gamepad). Su Android, ciò richiede che l'autorizzazione VIBRATE sia abilitata nella preimpostazione di esportazione Android prima di esportare il progetto.
Nota
La vibrazione può risultare fastidiosa per alcuni giocatori. Assicurarsi di inserire uno slider all'interno del gioco per disattivare la vibrazione o ridurne l'intensità.
Differenze tra input da tastiera/mouse e input da controller
Se sei abituato a usare tastiera e mouse, potresti rimanere sorpreso dal modo in cui i controller gestiscono certe situazioni.
Zona morta
A differenza di tastiere e mouse, i controller offrono assi con input analogici. Il vantaggio degli input analogici è che offrono maggiore flessibilità per le azioni. A differenza degli input digitali, che possono fornire solo valori di intensità pari a 0.0 e 1.0, un input analogico può fornire qualsiasi intensità tra 0.0 e 1.0. Lo svantaggio è che, senza un sistema di zona morta, l'intensità di un asse analogico non sarà mai pari a 0.0 a causa di come è fisicamente costruito. Rimarrà invece su un valore basso, come 0.062. Questo fenomeno è noto come drifting e può essere più evidente sui controller vecchi o difettosi.
Prendiamo come esempio concreto un videogioco di corse. Grazie agli input analogici, possiamo sterzare lentamente l'auto in una direzione o nell'altra. Tuttavia, senza un sistema di zona morta, l'auto sterzerebbe lentamente da sola anche se il giocatore non sta toccando il joystick. Questo perché l'intensità dell'asse direzionale non sarà uguale a 0.0 quando ci aspetteremmo che lo fosse. Poiché non vogliamo che la nostra auto sterzi da sola in questo caso, definiamo un valore di "zona morta" di 0.2 che ignorerà tutti gli input la cui intensità è inferiore a 0.2. Un valore ideale di zona morta è alto abbastanza da ignorare l'input causato dal drifting del joystick, ma basso abbastanza da non ignorare l'input reale del giocatore.
Godot integra un sistema di zone morte per affrontare questo problema. Il valore predefinito è 0.5, ma è possibile modificarlo per ogni azione nella scheda Mappa di input delle Impostazioni del progetto. Per Input.get_vector(), la zona morta si può specificare come 5° parametro facoltativo. Se non specificata, sarà calcolata la media delle zone morte da tutte le azioni nel vettore.
Eventi "Echo"
A differenza dell'input da tastiera, tenere premuto un pulsante del controller, come ad esempio una direzione del D-pad, non genererà eventi di input ripetuti a intervalli fissi (noti anche come eventi "eco"). Questo perché il sistema operativo non invia mai eventi "eco" per gli input dal controller.
If you want controller buttons to send echo events, you will have to generate InputEvent objects by code and parse them using Input.parse_input_event() at regular intervals. This can be accomplished with the help of a Timer node.
Focus della finestra
A differenza dell'input da tastiera, normalmente gli input dal controller possono essere rilevati da tutte le finestre del sistema operativo, comprese quelle non attive.
Sebbene ciò sia utile per funzionalità di terze parti per schermo diviso, può anche avere effetti negativi. I giocatori potrebbero inviare accidentalmente input del controller al progetto in esecuzione mentre interagiscono con un'altra finestra.
Se si desidera ignorare gli eventi di input del controller quando il progetto non è attivo, impostare ProjectSettings.input_devices/joypads/ignore_joypad_on_unfocused_application su true. Alternativamente, è possibile impostare Input.ignore_joypad_on_unfocused_application su true.
Prevenzione del risparmio energetico
A differenza dell'input da tastiera e mouse, gli input dal controller non inibisce le funzioni di sospensione e di risparmio energetico (come lo spegnimento dello schermo dopo un certo periodo di tempo).
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.
Risoluzione dei problemi
Vedi anche
You can view a list of known issues with controller support on GitHub.
My controller isn't recognized by Godot.
First, check that your controller is recognized by other applications. You can use the Gamepad Tester website to confirm that your controller is recognized.
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.
My controller works on a given platform, but not on another platform.
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).
Android
Come descritto all'inizio della pagina, il supporto per i controller sulle piattaforme mobili si basa su un'implementazione personalizzata anziché sull'utilizzo di SDL per gli input. Ciò significa che il supporto per i controller potrebbe essere meno affidabile in confronto alle piattaforme desktop.
Il supporto per gli input da controller basato su SDL sulle piattaforme mobili è previsto in una versione futura.
Web
Il supporto per i controller sul web è spesso meno affidabile rispetto alle piattaforme "native". La qualità del supporto tende a variare notevolmente tra i diversi browser. Pertanto, potrebbe essere necessario istruire i giocatori a utilizzare un browser diverso se non riescono a far funzionare il loro controller.
Come per le piattaforme mobili, Il supporto per gli input da controller basato su SDL sulla piattaforma web è previsto in una versione futura.