Programmare in C# – Gestione dell’Input
In questo tutorial vedremo come gestire l’input da bottoni o tasti, quindi gestiremo periferiche come tastiere o joypad come quello dell’Xbox One.
La classe Input
La classe Input in Unity fornisce una serie di funzioni statiche necessarie per gestire l’input. Unity registra l’input di continuo e ad ogni ciclo del gioco possiamo effettuare un polling, ovvero chiedere “È stato premuto il tasto X?” e agire di conseguenza.
Perché questo controllo sia effettuato ad ogni ciclo senza il rischio di mancare nessun input, è necessario inserirlo all’interno dell’Update.
Input da tastiera: la funzione GetKey
La funzione GetKey restituisce un valore booleano e serve a rilevare se è stato premuto un tasto oppure no. Per decidere quale tasto ci serve, Unity fornisce una classe KeyCode che contiene tutti i codici dei tasti, molto utile per superare la classica difficoltà di rilevare la pressione di tasti funzione (come Ctrl
, Alt
, F1
, etc.) su sistemi operativi diversi.
Inoltre, Unity fornisce tre funzioni per rilevare la pressione di un tasto:
- GetKeyDown, rileva la prima pressione;
- GetKey, rileva quando il tasto viene mantenuto premuto;
- GetKeyUp, rileva il rilascio del tasto.
Come abbiamo detto, il tutto va inserito all’interno della funzione Update. Facciamo un esempio con le tre funzioni:
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Debug.Log("Space");
}
if(Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Premuto Space");
}
if(Input.GetKeyUp(KeyCode.Space))
{
Debug.Log("Rilasciato Space");
}
}
Usare l’Input Manager e la funzione GetAxis
Immaginiamo un gioco platform: gestire il movimento del personaggio richiederebbe di rilevare l’input su almeno un asse orizzontale, per muoverlo a sinistra e a destra. Per fare ciò, dovremmo gestire due tasti (freccia destra e freccia sinistra). Ma se piuttosto che movimenti bruschi stile arcade, volessimo avere anche gli effetti di accelerazione e frenata nel movimento? Per fare questo ed altro, Unity mette a disposizione l’Input Manager.
Andando sotto Edit > Project Settings > Input
,
sarà possibile visualizzare l’Input Manager nel pannello Inspector.
Questa interfaccia permette di definire quelli che Unity chiama “assi”
di Input: non andiamo a leggere la pressione dei singoli bottoni, ma
lasciamo che la gestisca Unity.
In questo pannello, i singoli tasti possono essere accoppiati a due a due per creare degli assi di movimento, di cui noi poi possiamo leggere il valore. In breve, tornando all’esempio del platform di prima, non chiediamo a Unity quanto è stato premuto il tasto destro o quello sinistro ma “che valore ha l’asse di movimento orizzontale”, un valore che può variare fra -1 ed 1.
Gli “assi” di Unity non sono utilizzabili solo per gli assi verticale ed orizzontale, ma possono essere usati per influenzare qualunque valore debba crescere o decrescere in maniera non digitale, come ad esempio l’accelerazione di un automobile, una forza applicata ad un corpo, o l’intensità di un suono.
Per cominciare, definiamo quanti assi servono nel gioco immettendo un numero in alto nel pannello, sotto Axes:
Appena confermiamo il valore, vedremo scomparire gli altri assi, e rimarrà solo “Horizontal”. In quest’interfaccia, Positive button e Negative button
definiscono i due tasti che compongono l’asse. Nel nostro esempio, le
frecce da tastiera sono l’input principale, ma l’utente può anche
scegliere di premere i tasti A
o D
(“Alt” sta per “alternative”).
Anche se sotto Type scegliamo “Key or Mouse Button”, i valori di Gravity, Dead e Sensitivity ci permettono di fare in modo che l’input assomigli ad un vero joystick, quindi di avere un comportamento analogico e non digitale, con valori dell’asse intermedi fra 0 ed 1.
In pratica, premendo destra
il valore dell’asse cresce da 0 ad 1, secondo la velocità definita sotto Sensitivity
(maggiore è Sensitivity, più rapidamente arriverà ad 1). Una volta
arrivato ad 1 si ferma, e se lasciamo il tasto tenderà a tornare a 0 con
la velocità definita sotto Gravity.
Quando premiamo sinistra, il valore inizia a decrescere per poi andare verso -1. Se viene abilitato Snap, quello che succede è che se l’asse vale 1 (perché stiamo premendo destra) e premiamo rapidamente sinistra, l’asse scatterà a 0 prima di andare verso -1. Se Snap non è attivo l’asse decrescerà ‘dolcemente’ (ma dipende dalla Sensitivity) verso 0 e poi verso -1.
Passando alla programmazione, utilizziamo la funzione GetAxis per leggere il valore dell’asse, che sarà un float fra -1 ed 1. Ad esempio:
void Update()
{
Debug.Log(Input.GetAxis("Horizontal"));
}
Provate a premere i tasti e notate come cambiano i valori nella console. Provate anche a variare il valore di Sensitivity, portandolo a numeri piccoli come 0.1
, e notate come cambia il comportamento dell’asse.
È importante che la stringa con il nome dell’asse corrisponda a quello impostato nell’Input Manager, altrimenti Unity dà errore al momento di leggerne il valore.
Nota: il valore di Axis
non viene tenuto in considerazione nel caso Type
sia “Key or Mouse Button
“, ma solo se è “Joystick Axis
” (vedi sotto).
Input da joypad
Per rilevare l’input da joypad, è fondamentale utilizzare l’Input Manager.
Lo standard dei joypad è il controller dell’Xbox One, il cui supporto è nativo su Windows, mentre su Mac si può ottenere con il driver TattieBogle. Questo controller contiene molti assi e bottoni ed ognuno ha un nome specifico che va utilizzato in maniera precisa, ed in più variano a seconda della piattaforma. Per conoscere tutti i nomi, si possono consultare queste immagini.
Ad esempio, se volessimo rilevare l’asse verticale del secondo stick su Mac (“4th axis”, fare riferimento all’immagine di cui sopra), il setup nel pannello Input sarebbe così:
Da notare che, visto che si tratta di una levetta di movimento, non è necessario specificare i nomi dei bottoni, quindi i campi Button sono tutti vuoti. Si noti anche che Name è arbitrario, mentre è importante che Axis sia esattamente il quarto. Joy Num definisce che stiamo leggendo il valore dal primo joypad connesso.
A questo punto tarando Gravity e Sensitivity
possiamo regolare il nostro asse. In caso di un joystick vecchio o
difettoso la cui levetta non va mai esattamente al centro, il valore Dead torna utile per definire un’area intorno al centro dell’asse in cui il valore di questi, anche se rilevato come 0.00001
o un numero simile, viene considerato comunque come 0.
Per leggere quest’asse, possiamo usare un semplice GetAxis:
void Update()
{
float secStickVertical = Input.GetAxis("SecondaryVertical");
if(secStickVertical != 0f)
{
//Muovi il personaggio
//...
}
}