> For the complete documentation index, see [llms.txt](https://thebitcave.gitbook.io/guida-a-unity-bolt/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://thebitcave.gitbook.io/guida-a-unity-bolt/lezioni/utilizzare-le-coroutines.md).

# Lezione 04 - Utilizzare le Coroutines

In questa lezione andremo ad scoprire come utilizzare un Custom Event in modalità Coroutine.

In Unity, ma anche nella programmazione in generale, una [Coroutine ](https://docs.unity3d.com/Manual/Coroutines.html)è 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.).

{% hint style="info" %}
Per questa lezione, si consiglia di utilizzare la scena **Lezione 04 - Utilizzare le Coroutines** inclusa [nel progetto di supporto](https://github.com/thebitcave/gitbook-guida-bolt/releases).
{% endhint %}

### Aprire la Scena

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*

![Il grafo iniziale](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIPsr4UvJvhbtFj1I1%2F-MQIR8M37eujUueMCHAi%2Fgrafo_iniziale.png?alt=media\&token=46989f86-5563-40d3-9564-1d1ce2f4c217)

### Creare un Evento Personalizzato

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.

{% hint style="info" %}
Per avere una panoramica di come è possibile utilizzare gli Eventi Personalizzati, aprire la scena **Esempio 01 - Eventi Personalizzati** nel progetto di supporto.
{% endhint %}

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:

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIWqu4ewad2TDtzqo_%2F-MQIZ9nsuxjKE6oiMG6x%2Fevento_personalizzato.png?alt=media\&token=b5dcdbbd-4dc1-4399-a78c-dd9633229914)

### Attivare l'Evento

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*

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIWqu4ewad2TDtzqo_%2F-MQIZXuqSVEwCqcnTfz_%2Fesecuzione_evento.png?alt=media\&token=414d9c89-caf6-48a2-96ac-e753ff2aec4d)

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.

### Generare Elementi Multipli

Torniamo al nostro evento personalizzato: la nostra intenzione è di generare una serie di frecce invece di una singola.

{% hint style="info" %}
Per poter eseguire un numero finito di volte una serie di istruzioni, una delle possibilità è quella di usare l'unità **For Loop**.
{% endhint %}

* Tra i nodi *Custom Event* e *Instantiate*, inseriamo una unità For Loop, come mostrato nella figura seguente:

![Inserimento del ciclo For Loop](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIWqu4ewad2TDtzqo_%2F-MQIaI5x9d98I0MjdmEX%2Ffor_loop.png?alt=media\&token=61233946-f213-45e5-bc72-92b86da83e7a)

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.

### Temporizzare l'Esecuzione delle Unità

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](https://docs.unity3d.com/Manual/Coroutines.html) 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

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIWqu4ewad2TDtzqo_%2F-MQIdB6YqrfDu1RmJhHq%2Fcoroutine.png?alt=media\&token=9195492c-428c-47b9-aeda-1cfe033873bb)

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

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIdmFktwtGK6OxDpq5%2F-MQIeBj-6XP5bUB31aEl%2Fritardo_spawn.png?alt=media\&token=66c56b7c-672d-4053-9e28-a39b3f524f7e)

### Ultime Migliorie

Il sistema è funzionante, ma può essere migliorato con alcuni piccoli ritocchi.

#### Gestire il Numero di Oggetti Generati

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*

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIf1_v3kb6WrnOrupb%2F-MQIg-63YrkUPPiK70Rv%2Fargument_in.png?alt=media\&token=57559f9f-7bd8-437b-91e7-e5d279b4a27e)

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à

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIug8tP6KCkqtA0nW5%2F-MQIv1Zf8bN2Dk-2P9YT%2Ftrigger_arguments.png?alt=media\&token=dd6d6789-9f02-4f74-91a1-bb24b55aff97)

Una volta lanciata l'applicazione, sarà possibile notare che il numero di frecce generate è pari al valore passato.

#### Interrompere le Interazioni in fase di Esecuzione

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*

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIug8tP6KCkqtA0nW5%2F-MQIwkqIEDbt7e-tk3Zj%2Fvariables.png?alt=media\&token=d7ee74a1-554b-4ab6-957f-2a1dacbbfa67)

* 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*

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIug8tP6KCkqtA0nW5%2F-MQIxS2MPez8PFqijgIF%2Fbranch.png?alt=media\&token=90e5aac8-eae1-482a-bef7-9aa92a172216)

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*

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIug8tP6KCkqtA0nW5%2F-MQIykFxEMjx8qaFF0RE%2Fset_bool.png?alt=media\&token=aaf68f80-7988-4216-af30-d01f31ee5bec)

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

![](https://3114886391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKUGiR4TokVYSH1_yh6%2F-MQIug8tP6KCkqtA0nW5%2F-MQIzUZjWWfP5PPN6d4x%2Fset_bool_true.png?alt=media\&token=8d272856-06e1-45a6-aa28-a77248fe8d18)

Mandate in esecuzione l'applicazione e sarà possibile sparare solamente una volta terminato il ciclo di fuoco precedente.
