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...
Funzionalità dei controller
Godot supporta funzionalità specifiche per i controller che possono migliorare ulteriormente l'esperienza di gioco. Questa pagina descrive queste funzionalità, come sono state utilizzate nei giochi esistenti e come cominciare a usarle in Godot.
Avvertimento
Queste funzionalità dei controller sono attualmente supportate solo su Windows, macOS, iOS e Linux.
Avvertimento
A meno che tu non pubblicizzi specificamente il tuo gioco indicando che richiede controller particolari, ricorda che non vi è alcuna garanzia che i giocatori abbiano un controller con le funzionalità richieste.
Pertanto, consigliamo di utilizzare queste funzionalità per migliorare l'esperienza di gioco dei giocatori i cui controller le supportano, senza penalizzare chi non ne ha uno.
Colore del LED
Nei videogiochi, le luci LED di alcuni controller possono abbinarsi discretamente con l'esperienza di gioco sullo schermo, offrendo al giocatore effetti visivi corrispondenti nelle proprie mani. Ecco alcuni esempi notevoli:
In Hades, il colore della luce corrisponde al dio da cui si riceve un dono.
In Resident Evil 2, il colore della luce indica il livello di salute (verde per il massimo, giallo per media, rosso per bassa).
In Star Wars Jedi: Fallen Order, il colore della luce corrisponde al colore della spada laser.
Usa il metodo Input.set_joy_light() per impostare il colore dei LED di un determinato controller.
Per verificare se un controller supporta l'impostazione delle luci LED, usa il metodo Input.has_joy_light(). È risaputo che i controller PlayStation DualShock e DualSense supportano le luci LED.
Il seguente metodo _process() imposta il colore del LED in base al pulsante attualmente premuto, e lo spegne se nessun pulsante è premuto:
func _process(_delta):
var color := Color.BLACK
if Input.is_joy_button_pressed(0, JOY_BUTTON_A):
color = Color.BLUE
elif Input.is_joy_button_pressed(0, JOY_BUTTON_X):
color = Color.MAGENTA
elif Input.is_joy_button_pressed(0, JOY_BUTTON_B):
color = Color.RED
elif Input.is_joy_button_pressed(0, JOY_BUTTON_Y):
color = Color.GREEN
Input.set_joy_light(0, color)
L'esempio seguente sfuma gradualmente il colore del LED in un ciclo:
var hue = 0.0
func _process(delta):
var col = Color.from_hsv(hue, 1.0, 1.0)
Input.set_joy_light(0, col)
hue += delta * 0.1
L'esempio seguente fa lampeggiare il LED di rosso tre volte quando viene premuto il pulsante sud (Croce/X sui controller PlayStation):
var blink_tween: Tween = null
func _process(_delta):
var ready_to_blink = not blink_tween or not blink_tween.is_running()
if Input.is_joy_button_pressed(0, JOY_BUTTON_A) and ready_to_blink:
do_blink()
func do_blink():
if blink_tween:
blink_tween.kill()
blink_tween = create_tween()
blink_tween.tween_callback(func(): Input.set_joy_light(0, Color.RED))
blink_tween.tween_interval(0.2)
blink_tween.tween_callback(func(): Input.set_joy_light(0, Color.BLACK))
blink_tween.tween_interval(0.2)
blink_tween.set_loops(3)
Sensori di movimento (giroscopio e accelerometro)
Tramite i controlli di movimento, i giochi possono tracciare la rotazione e il movimento fisico del controller. Questo permette al giocatore di ruotare la telecamera di gioco muovendo il controller, o di scuoterlo per effettuare un'azione speciale.
Esistono diverse marche di controller che hanno integrato sensori giroscopici e accelerometri nei loro controller moderni, le due più importanti sono PlayStation e Nintendo. Da notare che i controller Xbox non hanno sensori di movimento al loro interno.
Per verificare se un controller connesso ha sensori di movimento, usa Input.has_joy_motion_sensors().
I sensori di movimento sono normalmente disabilitati per evitare di scaricare la batteria del controller quando i giochi non utilizzano queste funzionalità. Per abilitarli, chiama Input.set_joy_motion_sensors_enabled().
Si noti che gli assi dei valori riportati dai sensori di movimento dei controller sono sempre relativi all'orientamento naturale del controller stesso. Ecco un'immagine della mappatura degli assi per maggiore chiarezza:
I valori del giroscopio del controller mostrano la rotazione attorno ai rispettivi assi:
Il valore X dei dati del giroscopio indica la rotazione attorno all'asse X (rollio).
Il valore Y dei dati del giroscopio indica la rotazione attorno all'asse Y (imbardata).
Il valore Z dei dati del giroscopio indica la rotazione attorno all'asse Z (beccheggio).
L'accelerometro del controller fornirà i valori nei seguenti modi, rispettivamente:
Il movimento a sinistra e a destra è riportato come +X e -X.
Il movimento verso il basso e verso l'alto è riportato come +Y e -Y.
Il movimento via e verso l'utente è riportato come +Z e -Z.
Giroscopio
Il giroscopio è un tipo di sensore che rileva la rotazione del controller. Ecco alcuni esempi notevoli di uso del giroscopio nei videogiochi:
In Helldivers 2, Horizon Forbidden West, Star Wars: Dark Forces Remaster e Fortnite, inclinando il controller la telecamera ruota di conseguenza ("mira giroscopica"). Questo video di *Daven On The Moon* mostra e discute la mira giroscopica in modo più dettagliato.
In Death Stranding, BB può essere calmato ruotando delicatamente il controller.
L'esempio seguente ruota un oggetto utilizzando il sensore giroscopico di un controller. È possibile accedere a questo esempio anche consultando la documentazione di Input.start_joy_motion_sensors_calibration().
const GYRO_SENSITIVITY = 10.0
func _ready():
# In this example we only use the first connected joypad (id 0).
if 0 not in Input.get_connected_joypads():
return
if not Input.has_joy_motion_sensors(0):
return
# We must enable the motion sensors before using them.
Input.set_joy_motion_sensors_enabled(0, true)
# (Tell the users here that they need to put their joypads on a flat surface and wait for confirmation.)
# Start the calibration process.
calibrate_motion()
func _process(delta):
# Only move the object if the joypad motion sensors are calibrated.
if Input.is_joy_motion_sensors_calibrated(0):
move_object(delta)
func calibrate_motion():
Input.start_joy_motion_sensors_calibration(0)
# Wait for some time.
await get_tree().create_timer(1.0).timeout
Input.stop_joy_motion_sensors_calibration(0)
# The joypad is now calibrated.
func move_object(delta):
var node: Node3D = ... # Put your object here.
var gyro := Input.get_joy_gyroscope(0)
node.rotation.x -= -gyro.y * GYRO_SENSITIVITY * delta # Use rotation around the Y axis (yaw) here.
node.rotation.y += -gyro.x * GYRO_SENSITIVITY * delta # Use rotation around the X axis (pitch) here.
Si noti che prima di utilizzare i dati del giroscopio, è necessario prima calibrarlo chiamando Input.start_joy_motion_sensors_calibration() e Input.stop_joy_motion_sensors_calibration(). Questo perché i giroscopi moderni spesso necessitano di calibrazione. È come per una bilancia, che ha bisogno di calibrazione per sapere cosa è lo "zero". Come per una bilancia, solo un giroscopio correttamente calibrato fornirà una lettura accurata. Durante la calibrazione, l'utente posiziona il controller su una superficie piana. Il controller determina quindi quali valori riporta il giroscopio quando è effettivamente fermo (il suo "bias") e utilizza queste informazioni per rendere più precisi i dati di rotazione.
Consulta l'articolo su GyroWiki per informazioni su come utilizzare l'input del giroscopio come mouse.
Dopo aver abilitato e calibrato correttamente il giroscopio del controller, è possibile leggere i valori riportati tramite Input.get_joy_gyroscope().
Accelerometro
Avvertimento
Non utilizzare i dati dell'accelerometro per determinare la posizione del controller nello spazio 3D; gli accelerometri in generale non sono precisi abbastanza per questo.
Un accelerometro è un tipo di sensore che rileva l'accelerazione di un controller in m/s². Ad esempio, può rilevare se il giocatore alza rapidamente il controller, lo muove lateralmente o lo scuote.
L'accelerazione rilevata da un accelerometro include la gravità. Per ottenere solo l'accelerazione impressa dall'utente, bisogna sottrarre la gravità dall'accelerazione rilevata:
Input.get_joy_accelerometer(device) - Input.get_joy_gravity(device)
A causa di come funzionano gli accelerometri fisicamente, una volta che il movimento in una direzione si ferma, questi rilevano quasi immediatamente un movimento nella direzione opposta. Dopo aver riconosciuto il movimento in una direzione, potrebbe essere opportuno ignorare ulteriori letture per un breve periodo di tempo, al fine di evitare di riconoscere questo movimento opposto.
L'esempio seguente stampa il movimento del controller quando viene mosso rapidamente utilizzando il suo accelerometro. Se la sensibilità non sembra adeguata, è possibile regolare la costante THRESHOLD oppure sostituirla con un valore diverso nel codice sottostante.
var detect_accelerometer = true
# Change to make the game detect movement at different thresholds.
# With a lower value, smaller movements will be detected, and with a
# larger value, only big movements will be detected.
const THRESHOLD = 10.0
func _ready():
# In this example, we only use the first connected joypad (ID 0).
if 0 not in Input.get_connected_joypads():
return
if not Input.has_joy_motion_sensors(0):
return
# We must enable the motion sensors before using them.
Input.set_joy_motion_sensors_enabled(0, true)
func _process(delta):
if Input.has_joy_motion_sensors(0):
accelerometer_example()
func accelerometer_example():
if not detect_accelerometer:
return
var acceleration = Input.get_joy_accelerometer(0) - Input.get_joy_gravity(0)
if acceleration.length() > THRESHOLD:
if acceleration.x > THRESHOLD:
print("Moved left")
elif acceleration.x < -THRESHOLD:
print("Moved right")
if acceleration.y < -THRESHOLD:
print("Moved up")
elif acceleration.y > THRESHOLD:
print("Moved down")
if acceleration.z < -THRESHOLD:
print("Moved closer to the player")
elif acceleration.z > THRESHOLD:
print("Moved away from the player")
# After detecting movement in one direction, the accelerometer sensor
# will briefly report movement in the opposite direction, even though the controller only moved once.
# So we need to ignore these reported values for a short amount of time.
detect_accelerometer = false
await get_tree().create_timer(0.5, false).timeout
detect_accelerometer = true