Cos’è una UI? In genere una UI (o User Interface, cioè interfaccia utente) è ciò che si frappone fra l’utente ed un programma, al fine di rendere più semplice la comunicazione fra i due.
Ne sono un esempio le applicazioni che usiamo ogni giorno sui nostri smartphone, dove alla pressione di determinati pulsanti da parte dell’utente corrispondono diverse azioni svolte dall’applicazione.
In un videogioco possiamo sfruttare gli elementi dell’interfaccia utente in un miliardo di modi differenti: dai vari menù di avvio partita, pausa ed impostazioni a riquadri contenenti informazioni importanti per la partita in corso (ad esempio barre d’energia, munizioni e numero di vite disponibili) passando per la trascrizione di dialoghi a schermo e per la selezione di eventuali scelte morali da far prendere al giocatore.
Insomma, il cielo è l’unico limite,ed in questa lezione vedremo le basi del funzionamento di un’interfaccia utente e come creare interfacce utente con Unity!
Creare interfacce utente con Unity: Le basi
Negli ultimi tempi (cioè dalla versione 4.6 in poi) Unity ha adottato un sistema davvero molto semplice ed efficace per la gestione dell’interfaccia utente.
Per capire al meglio il funzionamento di questo sistema, iniziamo creando all’interno della nostra scena un oggetto di tipo “Text“ (Dal solito menù a tendina “Create“, lo troverai sotto “UI>Text“).
Come puoi facilmente immaginare non sarà altro che una scritta! Ma prima di soffermarci su come gestire (e modificare) un oggetto di tpo Text, ragioniamo per un attimo su come viene gestito dal punto di vista grafico e su cosa viene creato insieme ad esso all’interno della nostra scena!
Come puoi vedere dall’animazione precedente, il nostro Text (così come ogni altro elemento della UI) è un oggetto Bidimensionale, e inquanto tale non ha alcuna profondità!
Entrando in modalià 2D (premendo l’apposito pulsante nello Scene Panel), avremo la possibilità di modificarne posizione, rotazione e dimensione dalla stessa prospettiva da cui vedremo l’oggetto durante le fasi di gioco.
Un’altra proprietà fondamentale di un elemento di una UI è il suo Rect Transform. Tutti gli oggetti che abbiamo visto fino a questo momento possedevano un componente Transform per gestirne posizione, dimensione e rotazione, ma gli elementi di un’interfaccia grafica hanno un grossissimo problema con cui devono confrontarsi: Esistono un’infinità di schermi differenti là fuori, con dimensioni e risoluzioni diverse, e un’interfaccia deve necessariamente essere visibile per intero in qualsiasi tipo di schermo.
Il componente Rect Transform ci aiuterà proprio nella gestione degli ancoraggi degli elementi dell’interfaccia! Dando uno sguardo allo Hierarchy panel potrai notare che, oltre all’oggetto Text verranno creati anche una Canvas ed un Event System!
La Canvas (o tela, in italiano) è un po’ un contenitore: viene creato insieme al nostro primo oggetto della UI (sia esso un oggetto testuale, un pulsante, un’imagine o altro!) ed appare nella scena come un enorme rettangolo dai bordi bianchi, al cui interno verranno posizionati tutti gli elementi dell’interfaccia.
Per il momento ti basterà sapere che di default la canvas si adatta automaticamente alla dimensione dello schermo. Il componente Rect Transform di un elemento della UI dipende dalla canvas, quindi quando la canvas cambierà dimensioni anche gli elementi della UI contenuti in essa si disporranno in maniera differente!
L’altro oggetto che ci ritroveremo all’interno della scena è l’Event System. Esso si occuperà della gestione dei diversi input ricevuti dagli oggetti della nostra UI! Per fare un esempio, ipotizziamo di trovarci nel menù principale del nostro gioco: abbiamo davanti i pulsanti “Nuova partita”, “Continua” ed “Opzioni”. Se il gioco è in funzione su un pc, andremo a premere i pulsanti tramite mouse, mentre se stiamo giocando su un tablet, lo faremo tramite il touchscreen. l’event system gestirà questi diversi tipi di input “sotto il cofano”, nascondendone la complessità ai nostri occhi!
Interazione con un text object
In questa sezione vedremo come interagire con un text object tramite script.
Per prima cosa, occorre riposizionare il text object e renderlo un po’ più leggibile. Ingrandisci l’oggetto e, dal suo Inspector Panel, aumenta il parametro “Font Size“, imposta il “Font Style” su “Bold” ed allinea il tutto al centro tramite gli appositi bottoni “Alignment“. Inoltre, cliccando sull’icona di forma quadrata all’interno del componente rect transform ti ritroverai davanti una serie di preset per riposizionare la scritta. Tenendo premuti i pulsanti Alt e Shift, clicca sull’icona centrale. In questo modo il testo verrà spostato al centro della canvas (e di conseguenza al centro dell’inquadratura).
Adesso che la scritta risulta ben leggibile siamo pronti a procedere al prossimo punto! Dobbiamo creare uno script che ci permetta di manipolare il campo text.
La prima cosa da fare quando si ha a che fare con uno script riguardante l’interfaccia, è inserire il relativo namespace. Ma cos’è un namespace?
Senza perderci per strada, possiamo dire che un namespace ci consente di accedere con maggior facilità a determinati tipi di dato o funzioni. Nel caso specifico, per manipolare un oggetto text dobbiamo definire una variabile di tipo Text, ma il tipo Text rientra nel namespace UnityEngine.UI. quindi, in codice, dovremmo scrivere qualcosa di simile:
public UnityEngine.UI.Text mioTesto;
Inseriamo il relativo namespace scrivendo “using UnityEngine.UI” nelle primissime righe del nostro script, così da poter dichiarare una variabile testuale scrivendo semplicemente qualcosa del genere:
public Text mioTesto;
Detto ciò, vediamo un po’ il corpo dello script (che ho chiamato UserInterfaceScript) :
using UnityEngine; using System.Collections; using UnityEngine.UI; public class UserInterfaceScript : MonoBehaviour { private Text miotesto; private int contatore = 0; // Use this for initialization void Start () { miotesto = GetComponent<Text>(); miotesto.text = "Hai premuto il tasto " + contatore + " volte"; } // Update is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.A)){ contatore = contatore + 1; miotesto.text = "Hai premuto il tasto " + contatore + " volte"; } } }
Lo script è molto simile a ciò che abbiamo visto in passato, con l’unica eccezione che quello che una volta facevamo apparire nel pannello di debug tramite la funzione Debug.Log adesso appare a schermo tramite la manipolazione dell’oggetto testuale!
UI Button: interazione coi pulsanti
Ma se volessimo interagire con un pulsante? Anche in questo caso sarà tutto molto semplice: l’event system di cui abbiamo parlato prima gestirà tutto ciò che riguarda la pressione del tasto! Tutto ciò che noi dovremo fare sarà creare un nuovo tasto e collegare il tasto alla funzione di uno script.
Creiamo quindi un nuovo tasto all’interno della scena tramite il solito menù create ( sotto UI>Button) e riposizioniamolo all’interno della canvas. Come potrai notare, l’oggetto che abbiamo appena creato avrà un text field come figlio! Eliminiamo questo text field (non ne avremo bisogno!) ed importiamo all’interno del nostro progetto questa fantastica immagine che ho preparato per l’occasione.
Cambiamo il tipo di texture dell’immagine da “texture” a “Sprite (2D and UI)” ed impostiamola come immagine del nostro pulsante, spuntando poi la casella “preserve aspect” per far in modo che il pulsante mantenga lo stesso rapporto fra altezza e larghezza. Adesso siamo pronti per il prossimo passo!
Dopo aver fatto ciò apportiamo delle piccole modifiche allo script precedente, in modo che il contatore aumenti non alla pressione di un tasto della tastiera, ma alla pressione del nostro tasto a schermo.
using UnityEngine; using System.Collections; using UnityEngine.UI; public class UserInterfaceScript : MonoBehaviour { private Text miotesto; private int contatore = 0; // Use this for initialization void Start () { miotesto = GetComponent<Text>(); miotesto.text = "Hai premuto il tasto " + contatore + " volte"; } public void FunzioneTasto(){ contatore = contatore + 1; miotesto.text = "Hai premuto il tasto " + contatore + " volte"; } }
Come puoi vedere adesso la funzione Update non sarà più necessaria, ma è stata rimpiazzata da un’altra funzione (che ho chiamato “FunzioneTasto“). Presto assegneremo questa singola funzione al tasto che abbiamo creato in precedenza, in modo tale che il codice contenuto in essa venga eseguito una volta ad ogni pressione del bottone!
Ricorda che questa funzione deve essere accessibile dall’esterno dello script, quindi deve essere dichiarata come public.
Adesso colleghiamo la funzione al pulsante: selezioniamo quindi il pulsante e dal suo inspector panel scorriamo fino alla fine del componente Button, dove troveremo una finestra chiamata “On Click ()“. Clicchiamo quindi sul pulsante “+” e dall’apposito menù selezioniamo l’oggetto contenente lo script precedentemente creato (cioè l’oggetto text!) . Dal menù a tendina inizialmente impostato su “No Function” troveremo una lista di funzioni. Selezioniamo “UserInterfaceScript>FunzioneTasto ()“…et voilà! Andando in play mode il pulsante farà aumentare il contatore.
Chiaramente in questo modo il pulsante può svolgere qualsiasi funzione all’interno del gioco, sta a te scegliere cosa esso debba fare e scriverne il relativo codice!
Conclusione
Come puoi immaginare ci sarebbe molto altro da dire, e quelli che abbiamo esaminato in questa lezione sono solo gli elementi fondamentali e che ti ritroverai più spesso tra le mani nel creare interfacce utente con Unity. Con questa lezione inoltre chiudiamo la parte logica del nostro corso, infatti dalla prossima lezione applicheremo i concetti che abbiamo appreso fino ad ora per creare un videogioco!