Programmare in C# e Unity3D – L’input da mouse, touch e sensori

20 Settembre 2019

Proseguendo con il discorso sull’input, parliamo ora degli input provenienti da mouse, oppure dall’accelerometro o dal touch screen di un device.

Input del mouse

Così come abbiamo fatto per l’input da tastiera, anche per il mouse è disponibile una funzione che rileva la pressione dei vari tasti, a cui è necessario passare solo l’indice del tasto premuto (0 per il sinistro, 1 per il destro, e così via).

Ad esempio:

void Update ()
{
    if(Input.GetMouseButton(0))
    {
        Debug.Log("Mouse");
    }


    if(Input.GetMouseButtonDown(0))
    {
        Debug.Log("Bottone premuto");
    }
    if(Input.GetMouseButtonUp(0))
    {
        Debug.Log("Bottone rilasciato");
    }
}

Da notare che la funzione Input.GetMouseButton(0) rileva anche il touch su cellulare, ma solo il primo tocco che viene effettuato (ovvero, non funziona se sullo schermo è posizionato più di un dito).

Posizione del mouse

Come visto, rilevare la pressione di un tasto del mouse è abbastanza semplice. Come possiamo però sapere “dove” l’utente sta cliccando? I metodi sono diversi, vediamone i due principali.

Innanzi tutto, per sapere dove l’utente ha cliccato, abbiamo la posizione del mouse in pixel, in un Vector2 leggibile dalla variabile Input.mousePosition. Poiché non sappiamo a priori quale sarà la risoluzione dello schermo dell’utente, non possiamo operare sui pixel (un utente che clicca al centro potrebbe star cliccando a 400px su un netbook, ma anche a 910px in un full HD).

Per questo motivo, è necessario convertire la posizione del mouse in un raggio che viene sparato dalla camera nella direzione che corrisponde al punto cliccato sullo schermo. Possiamo fare tutto ciò con la funzione ScreenPointToRay, a cui dobbiamo solo passare le coordinate del mouse. In seguito, come visto in una lezione precedente, mediante Physics.Raycast possiamo scoprire se il raggio tocca un Collider nella scena, il che vuol dire che il mouse ha cliccato effettivamente su qualcosa. Va da sé che qualunque oggetto cliccabile dovrà essere fornito di un Collider attivo della dimensione necessaria.

Facciamo tutto ciò in congiunzione con l’uso del tasto sinistro del mouse come tasto “di fuoco”:

void Update()
{
    if(Input.GetButtonDown(0))
    {
        Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast(mouseRay))
        {
            // Qualcosa è stato colpito!
        }
    }
}

In questo esempio, appena il tasto sinistro viene premuto viene creato un raggio (mouseRay) a partire dalla camera principale della scena (Camera.main), e se questo colpisce qualcosa possiamo impostare il risultato del click nell’if.

Se dovessimo aver bisogno di oggetti con un Collider ma non cliccabili, basterà spostarli su un layer differente e poi fare il controllo sul raggio mascherando il raycast con una maschera di livello, come visto nella lezione sul raycasting.

Input touch e multitouch

In modo molto simile a come viene rilevato l’input del mouse, possiamo leggere l’input di uno schermo touch screen. Inoltre, la lettura del touch screen viene facilitata in Unity perché indipendentemente dalla piattaforma (che sia iOS o Android) Unity fornisce un array di elementi Touch (ovvero Input.touches) che corrisponde a tutti i tocchi attivi in un certo momento, quindi possiamo trattare i tocchi allo stesso modo indipendentemente dal device.

Ognuno di questi elementi Touch possiede molte informazioni utili: la posizione a schermo, la fase del tocco (iniziato, mantenuto, terminato, molto simili a GetKeyDown, GetKey e GetKeyUp), ed il numero del dito che sta producendo il tocco.

Vediamo un esempio:

foreach(Touch t in Input.touches)
{
    switch(t.phase)
    {
		case TouchPhase.Began:
			Debug.Log ("Nuovo tocco: " + t.fingerId + " pos: " + t.position.x + " " + t.position.y);
			break;
		case TouchPhase.Moved:
		case TouchPhase.Stationary:
			Debug.Log ("Tocco continuato: " + t.fingerId + " pos: " + t.position.x + " " + t.position.y);
			break;
		case TouchPhase.Ended:
		case TouchPhase.Canceled:
			Debug.Log ("Tocco terminato: " + t.fingerId + " pos: " + t.position.x + " " + t.position.y);
			break;
    }
}

In questo esempio, scorriamo l’array dei tocchi in un dato momento (ammesso che ce ne siano!) tramite un ciclo foreach e stampiamo a schermo le coordinate di tutti i tocchi presenti sul touch screen, distinguendoli (mendiante uno switch) in base alla fase in cui si trova il tocco (t.phase).

Lavorare con il multitouch

È importante notare come il device, ovviamente, non ha una percezione di quale dito sta toccando lo schermo. Se ad esempio premiamo lo schermo con l’indice, questo tocco sarà il primo dell’array Input.touches, ed avrà fingerId 0. Se premiamo anche con il medio, questo sarà il secondo tocco nell’array Input.touches, ed avrà fingerId 1.

Se ora solleviamo l’indice, il tocco che corrisponde al medio, essendo l’unico rimasto, sarà il primo dell’array (Input.touches[0]). Per riconoscere che è sempre lo stesso, torna utile la variabile fingerId, che avrà ancora valore 1.

Allo stesso modo, premendo con tre dita nell’ordine indice, medio ed anulare, avremo un array di tre elementi. Se solleviamo l’indice ed il medio, e poi successivamente ripremiamo con l’indice, avremo un array di due elementi (che nella realtà sono medio ed anulare) in cui non per forza Input.touches[0] sarà il medio e Input.touches[1] l’anulare, quindi dobbiamo basarci sul fingerId per sapere quale tocco corrisponde a quale dito.

In definitiva, lavorare con il multitouch presenta una serie di difficoltà relative alla gestione dei singoli tocchi, che richiede una considerevole quantità di codice.

Unity Remote: testare le caratteristiche mobile su desktop

Poiché il tocco viene registrato solo su mobile ma lì non abbiamo modo di usare Debug.Log, in mancanza di un computer che rilevi il tocco (come un tablet Surface), per poter testare i tocchi direttamente nell’editor l’unico modo è ricorrere a Unity Remote.

Unity Remote è una piccola app per iOS o Android, che permette di collegare un device (che sia un telefono o un tablet) ad una istanza di Unity in esecuzione sul computer tramite wi-fi, ed inviare al gioco input dal touch screen o dall’accelerometro. Unity a sua volta invia al device un video a bassa risoluzione del gameplay, in modo da poter effettuare l’input in maniera informata.

L’app è gratuita e scaricabile dagli store (App Store o Google Play) ed è uno strumento fondamentale per lo sviluppo di app gioco su questi device. L’alternativa sarebbe creare una build ogni volta che facciamo una piccola modifica, un’operazione lunga e troppo costosa nel processo di sviluppo.

In definitiva però, prima di pubblicare un gioco bisogna sempre testarlo sul device di riferimento, anche perché l’input di Unity Remote arriva con molto ritardo al computer, quindi sul device si potrebbero avere risultati leggermente diversi.

Rilevare i movimenti dell’accelerometro

Così come per il touch, anche per l’accelerometro Unity fornisce un’interfaccia unificata indipendentemente dal device: Input.acceleration, che consiste in un Vector3 che corrisponde all’accelerazione gravitazionale del device. Purtroppo, l’orientamento di questo vettore può variare di device in device, quindi a volte sarà necessario procedere per esperimenti e scoprire come è orientato.

Ad esempio poggiando il device su un tavolo, se la componente z di questo vettore assume un valore positivo mentre le altre due componenti valgono 0, vuol dire che il vettore è orientato con Z verso lo schermo, Y verso l’alto, e X verso il lato destro del telefono.

Unity3D: rilevare i movimenti dell’accelerometro

L’orientamento degli assi va però testato device per device e, in caso di differenze, sarà necessario inserire nel codice un controllo sul tipo di device utilizzato, e riordinare gli assi.

Facendo delle prove ci si renderà conto che l’accelerometro restituisce valori molto sporchi, dove i numeri non sono precisi ma tendono ad oscillare anche se il device viene tenuto su una superficie stabile. Questo perché l’accelerometro per sua natura è impreciso, ed inoltre risente di tutte le forze magnetiche anche minime nell’area circostante. Per questo motivo spesso l’accelerometro non viene usato per controllare personaggi con precisione, ma solo come misuratore degli scossoni dati al telefono.

Ad esempio:

void Update()
{
    Vector3 deviceAcceleration = Input.acceleration;
    if(deviceAcceleration.magnitude > 10f)
    {
        Debug.Log("Il device è stato scosso forte");
    }
}

Questo semplice codice legge il valore della magnitudine del vettore di accelerazione, per ricavare la forza con cui è stato scosso il device. Se questa supera 10 (un valore di esempio a caso), possiamo considerare che sia stato scosso forte.

Anche per l’accelerometro vale il discorso di Unity Remote di cui sopra: poiché non sarebbe possibile testare i valori del sensore se non facendo una build, questa app permette di testare rapidamente questo metodo di controllo durante lo sviluppo.

Articoli recenti

Commenti recenti

  1. Massimiliano Ferretti su I Commenti

    Mi permetto di aggiungere una mia considerazione personale che ho riportato dall'utilizzo di C#. Personalmente mi piace commentare funzioni e…

  2. Personalmente ritengo che utilizzare git porti sempre dei vantaggi anche per lo sviluppo solo. Già solo la possibilità di fare…

  3. ciao, il link a discord non è piu valido, vorrei utilizzare il materiale che hai pubblicato tempo fa, come faccio?

Itamde è anche una scuola di programmazione online.

Itamde

Impara ciò che desideri, al tuo ritmo

0 commenti

Invia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Potrebbe interessarti anche…

Le novità di Itamde Studio – Ottobre 2025

Le novità di Itamde Studio – Ottobre 2025

Tra creazioni, libri e un po’ di magia artigianale L’autunno è arrivato e Itamde Studio prosegue la sua stagione creativa con la consueta energia poliedrica: tra scrittura, web, video, artigianato e nuovi progetti in vista dei mercatini di fine anno. Questo mese di...

Rimani aggiornato sulle ultime notizie e novità

Accedi ai contenuti riservati

Scopri il dietro le quinte dei nostri progetti, risorse esclusive e lo stato di avanzamento delle nostre creazioni in tempo reale.

Iscriviti alla newsletter

Ricevi le nostre notizie, le nostre riflessioni creative e le novità dell’atelier direttamente nella tua casella di posta elettronica.

Seguici

Unisciti alla nostra community sui social network per seguire i nostri progetti quotidiani e interagire con noi.