Lezione 04 - Utilizzare le Coroutines
In questa lezione andremo ad scoprire come utilizzare un Custom Event in modalità Coroutine.
Last updated
In questa lezione andremo ad scoprire come utilizzare un Custom Event in modalità Coroutine.
Last updated
In Unity, ma anche nella programmazione in generale, una Coroutine è una funzione che può essere messa in pausa e riattivata all'avverarsi di alcuni particolari eventi (es.: al frame successivo, dopo un determinato periodo, etc.).
Per questa lezione, si consiglia di utilizzare la scena Lezione 04 - Utilizzare le Coroutines inclusa nel progetto di supporto.
Una volta aperta la scena di supporto, sarà possibile visualizzare un oggetto Spawner:
Selezioniamo il gameobject Spawner e notiamo che è già presente il componente Flow Machine.
Apriamo il grafo cliccando su Edit Graph nell'Inspector
Noteremo che è presente un singolo evento Update che intercetta la pressione del tasto Space
Un Evento Personalizzato (Custom Event) ci permette di creare un evento simile a quelli già presenti in Unity ma che potremo eseguire a nostro piacimento dallo stesso grafo o da grafi esterni.
Per avere una panoramica di come è possibile utilizzare gli Eventi Personalizzati, aprire la scena Esempio 01 - Eventi Personalizzati nel progetto di supporto.
Un Evento Personalizzato è di solito formato da due entità:
L'evento vero e proprio: che andrà ad eseguire i nodi contenuti
L'attivatore dell'evento (trigger): che comanderà all'evento di eseguire il suo contenuto
Nel nostro caso vogliamo generare una serie di oggetti in una sequenza temporizzata (es.: generare dieci frecce una alla volta).
Cominciamo con il creare un Evento Personalizzato:
Nel grafo dello Spawner, clicchiamo il pulsante destro in uno spazio vuoto e selezioniamo Event > Custom Event
Nel secondo campo (quello con l'identificatore arancione) inseriamo il nome dell'evento: SpawnElements
In modo del tutto simile a quanto fatto nella Lezione 03, generiamo un prefab (Arrow) aggiungendo un nodo Instantiate, come mostrato nella seguente immagine:
Al contrario degli eventi di Unity, un evento personalizzato deve essere lanciato all'interno del nostro codice tramite un attivatore (Trigger):
Dall'uscita True del nodo Branch, clicchiamo e trasciniamo creando un nodo Event > Trigger Custom Event
Nel secondo campo (quello con l'identificatore arancione) inseriamo il nome dell'evento che vogliamo eseguire: SpawnElements
Provando ad eseguire l'applicazione, potremo notare che la freccia viene generata ogni volta che andremo a premere la barra spaziatrice.
Rispetto alla lezione precedente, abbiamo slegato l'esecuzione dei nodi che generano la freccia dal controllo dell'interazione con il giocatore.
Torniamo al nostro evento personalizzato: la nostra intenzione è di generare una serie di frecce invece di una singola.
Per poter eseguire un numero finito di volte una serie di istruzioni, una delle possibilità è quella di usare l'unità For Loop.
Tra i nodi Custom Event e Instantiate, inseriamo una unità For Loop, come mostrato nella figura seguente:
Notare che il pin di uscita utilizzato è Body: tutto ciò che segue verrà eseguito una volta per ogni ciclo (nel nostro caso, 10 volte).
Il nodo Exit ci permette di "proseguire" l'esecuzione di altro codice una volta finiti i cicli.
Provate ad eseguire l'applicazione: noterete che, ogni volta che viene premuta la barra spaziatrice, vengono generate 10 frecce contemporaneamente.
I comandi vengono solitamente eseguiti immediatamente uno dopo l'altro e non è possibile "aspettare" del tempo prima di eseguire quello successivo. Per poter effettuare una operazione di questo tipo, è necessario ricorrere ad una Coroutine che non segue il regolare svolgersi dei comandi e può essere messa in pausa.
Dobbiamo prima di tutto trasformare il nostro evento personalizzato in una Coroutine:
Selezioniamo il Custom Event e, nel Graph Inspector, selezioniamo la spunta Coroutine
Noteremo che nella unità apparirà una icona identificativa
Per temporizzare l'esecuzione dei comandi, aggiungiamo un ritardo:
All'uscita del nodo Instantiate, aggiungiamo il nodo Time > Wait for Seconds
Nel campo Delay, inseriamo il valore 0.2 (secondi)
Provate ad eseguire l'applicazione e vedrete che ora le frecce vengono generate una di seguito all'altra con un ritardo di 200 millisecondi
Il sistema è funzionante, ma può essere migliorato con alcuni piccoli ritocchi.
Al momento il numero di elementi generati è fissato a 10: possiamo rendere più flessibile il nostro evento personalizzato tramite l'aggiunta di un parametro (Argument):
Nel nodo Custom Event, sostituire inserire il valore 1 nel campo Arguments
Apparirà un pin in uscita di colore verde
Collegare il pin (che sarà il nostro parametro in ingresso) con il valore Last dell'unità For Loop
Il parametro in ingresso dovrà essere "passato" dal trigger:
Nell'unità Trigger Custom Event inseriamo il valore 1 nel campo Arguments: comparirà un pin in ingresso
Collegare il nuovo pin ad una unità int Literal
Assegnare un valore maggiore di zero all'unità
Una volta lanciata l'applicazione, sarà possibile notare che il numero di frecce generate è pari al valore passato.
Per come è strutturata l'applicazione, è possibile generare più serie di eventi sovrapposti (ad esempio, premendo più volte la barra spaziatrice). Per migliorare l'interazione, sarebbe meglio pensare di disattivare l'interazione con il giocatore fino a che il ciclo non abbia terminato di eseguire i comandi.
Per fare questo utilizzeremo una variabile booleana che indica se il ciclo è in esecuzione oppure no.
Creiamo una Graph Variable (nel pannello Variables) di tipo bool e chiamata canShoot
Assegnamole un valore di partenza true
Trasciniamo la variabile appena creata nel grafo, vicino all'unità Input.GetKeyDown
Colleghiamo le due unità tra loro con una unità Logic > And
Colleghiamo il pin di uscita di And al pin di entrata del Branch
Lo schema appena creato ci permette di lanciare l'evento solo se è stata premuta la barra spaziatrice e la variabile canShoot è vera. Vogliamo che la variabile diventi falsa durante l'esecuzione del ciclo.
Spostiamoci nel evento personalizzato e tra il nodo Custom Event e il For Loop inseriamo una unità Variable > Graph > Set Graph Variable
Impostiamo il nome della variabile a canShoot
Assegnamo un bool Literal al pin di ingresso con valore false
Appena prima di cominciare il ciclo, la variabile viene impostata ad un valore falso, impedendo così all'evento update di generare ulteriori eventi.
Nel pin Exit dell'unità For Loop, inseriamo gli stessi elementi di sopra, ma il bool Literal dovrà essere true, in modo tale da riattivare la possibilità di sparare
Mandate in esecuzione l'applicazione e sarà possibile sparare solamente una volta terminato il ciclo di fuoco precedente.