PREMESSA:
Se state imparando a programmare questa lezione sarà fondamentale per entrare nel meccanismo di ragionamento che vi aprirà le porte della programmazione. Che usiate Unity o no, in linguaggio C# o altro linguaggio, il sistema di ragionamento per entrare nei meandri della programmazione è il medesimo ed è alla base delle lezioni future. Dunque fare vostri questi concetti è di fondamentale importanza.
INIZIAMO:
Abbiamo già parlato sommariamente dell’istruzione if nella sessione 3 ed ora vedremo come utilizzarla concretamente così da prendere confidenza con le istruzioni di controllo ovvero quelle istruzioni che controlleranno il flusso del programma. Essi vengono chiamati anche costrutti.
I costrutti non sono molti, comunque noi, per le prime lezioni, vedremo solo quelli principali, partendo appunto dall’if…else.
if è un costrutto a se stante e come abbiamo visto, può esistere anche da solo.if(nome=="Mario"){fai questo;}
else è una altro costrutto che però è sempre associato ad un if.
else significa “altrimenti“, ovvero eseguirà le istruzioni solo quando l’if a cui è legato non è vero.
In pratica:
SE(nome==”Mario”)
{
fai questo
}
ATRIMENTI
{
fai quest’altro
}
if(nome=="Mario")
{
fai questo
}
else
{
fai quest'altro
}
Ci siamo già imbattuti nei due uguali, uno dietro l’altro e ci saremo chiesti il perché di due simboli invece che uno solo.
Tutti i simboli sono detti operatori, il più, il meno, il diviso, gli uguale ecc… Parleremo più in dettaglio degli operatori nell’apposita sessione, per ora vi basti sapere che :
pippo=5
è diverso da
pippo==5
– Quando si usa un solo simbolo uguale si sta facendo un’assegnazione, ovvero si sta impostano pippo uguale a 5.
– Mentre, quando si useranno due simboli uguale uno dopo l’altro si sta facendo un controllo, in pratica ci si sta chiedendo: pippo è uguale a 5?
In pratica i due uguale stanno ad intendere una domanda: “Ma pippo è uguale a “Mario”?“
Mentre un solo uguale è un’affermazione: “pippo è uguale a “Mario”.
Il simbolo == fa parte degli operatori chiamati di confronto (o relazionali) che, come suggerisce il nome, mettono in relazione due valori e li confrontano.
Proviamo a fare un esempio più concreto.
Ricordiamoci che una variabile di tipo bool è una variabile che può avere solo due valori, vero o falso, in inglese true o false.
Vediamo come verificare se il giocatore è in possesso di una chiave per aprire una porta.
Nel caso ne sia in possesso eseguirà un metodo, altrimenti ne eseguirà un altro.
public class Player : MonoBehaviour {
//Dichiaro la variabile di tipo bool che mi servirà
bool chiaveRossaRaccolta;
//Metodo che si esegue quando il player tenta di aprire la porta Rossa
void AzioneSullaPortaRossa()
{
if(chiaveRossaRaccolta==true)
{
ApriLaPortaRossa();
}
else
{
MessaggioNoChiave();
}
}
Cosa fa questo script è abbastanza ovvio.
Ci troviamo nella calsse Player, script che ipoteticamente sarà attaccato sul gameObject del giocatore.
Ribadiamo il concetto che un metodo può definirsi come un blocco di codice autonomo che viene richiamato tramite il suo nome.
Quando il giocatore tenterà di aprire la porta verrà eseguito il metodo AzioneSullaPortaRossa().
All’interno di esso avviene un controllo.
Se la variabile chiaveRossaRaccolta risulta true (vera) allora verrà eseguito il metodo ApriLaPortaRossa(), al contrario, se la variabile chiaveRossaRaccolta risulta false (falsa), verrà eseguito il codice dentro l’else, ovvero verrà eseguito il metodo MessaggioNoChiave(), che ipoteticamente visualizzerà un messaggio sullo schermo informando il giocatore che per aprire quella porta è necessaria la chiave rossa.
Le parentesi graffe rappresentano lo scopo del nostro if, ovvero le istruzioni che dovrà eseguire. Allo stesso modo, le parentesi graffe che seguono l’istruzione else rappresentano lo scopo dell’else.
All’interno dello scopo del nostro if potremmo inserire anche molteplici istruzioni, tipo:
//Metodo che si esegue quando il player tenta di aprire la porta Rossa
void AzioneSullaPortaRossa()
{
if(chiaveRossaRaccolta==true)
{
ApriLaPortaRossa();
AggiungiPuntiAlGiocatore();
EliminaChiaveRossaDaInventario();
}
else
{
MessaggioNoChiave();
}
Ovvero, se nel momento in cui il player tentasse di aprire la porta rossa, se risultasse vero che esso è in possesso della chiave rossa, verranno eseguiti i tre metodi:
- ApriLaPortaRossa();
- AggiungiPuntiAlGiocatore();
- EliminaChiaveRossaDaInventario();
Dovremmo aggiungere dunque anche i tre metodi nella nostra classe che risulterà tipo:
public class Player : MonoBehaviour { //Con questa parentesi graffa apro la classe
//Dichiaro la variabile di tipo bool che mi servirà
bool chiaveRossaRaccolta;
//Metodo che si esegue quando il player tenta di aprire la porta Rossa
void AzioneSullaPortaRossa()
{
//Se chiaveRossaRaccolta è vera
if(chiaveRossaRaccolta==true)
{
ApriLaPortaRossa();
AggiungiPuntiAlGiocatore();
EliminaChiaveRossaDaInventario();
}
else //Se chiaveRossaRaccolta è falsa
{
MessaggioNoChiave();
}
} //Con questa parentesi graffa chiudo il metodo AzioneSullaPortaRossa()
void ApriLaPortaRossa()
{
//Animazione della porta che si apre
}
void AggiungiPuntiAlGiocatore()
{
//Aggiungi 1000 punti al giocatore
}
void EliminaChiaveRossaDaInventario()
{
//Elimina la chiave rossa dall'inventario
}
void MessaggioNoChiave()
{
//Invia un messaggio su schermo con scritto "non possiedi la chiave Rossa"
}
}//Con questa parentesi graffa chiudo la classe
Finchè il metodo AzioneSullaPortaRossa() non verrà eseguito, non succederà nulla e tutti i metodi
ApriLaPortaRossa();
AggiungiPuntiAlGiocatore();
EliminaChiaveRossaDaInventario();
MessaggioNoChiave();
saranno “dormineti”, cioè non verranno mai eseguiti.
I primi tre metodi verranno eseguiti solamente se nel momento dell’esecuzione di
AzioneSullaPortaRossa()
la variabile chiaveRossaRaccolta risultasse true (vera).
Il metodo MessaggioNoChiave();
non verrà mai eseguito a meno che, nel momento in cui viene eseguito
AzioneSullaPortaRossa()
la variabile chiaveRossaRaccolta risulti false (falsa).
17 pensieri su “La prima istruzione di controllo If … else”
Ottima spiegazione. Semplice ed efficace.
Ti seguo con interesse! 😉
Grazie Marco. 😀
Quando scrivo mi sforzo di calarmi nei panni di chi non ha mai esplorato il mondo della programmazione!
Complimenti per come spieghi i concetti della programmazione ad oggeti che da anni vorrei imparare.
Ho da fare una sola domanda, cosa significa il nome della classa seguito da “:MonoBehaviour” ?
public class Player : MonoBehaviour {
Grazie
Ciao Fabrizio, grazie per i complimenti.;)
Come accennato nella sessione dedicata alla panoramica su uno script in unity, MonoBehaviour è la classe che identifica un componente (o script) di Unity, ovvero la classe base da cui derivano tutti gli scripts, i metodi e le classi di Unity. Behaviour significa appunto “comportamento generico”. I metodi Start(), Update() ecc… esistono proprio perché essi sono metodi della classe MonoBehaviour. Così come per i metodi GetComponent() e tutte le altre funzioni proprie di Unity.
davvero una guida ben scritta ed efficace, complimenti! (dopo anni che mi riprometto di imparare, e dopo più di 20 che non programmo niente, chissà se ormai arrivato ai 40 non sia la volta buona 🙂 ).
stampata e raccolta in fascicoli, sono giorni che non leggo altro, una domanda però avrei da farti (giusto per vedere se ho capito bene) quando scriviamo “public class xxxx : MonoBehaviour”, quel MonoBehaviour” serve al compliatore (visual studio) per capire che stiamo usando parole chiave, sintassi e grammatica di Unity?
Grazie,e scusate per la domanda se sembra stupida 🙂
Ciao Marco, grazie delle belle parole.
Si, la parola MonoBehaviour indica proprio la classe base da cui derivano tutti gli scripts di Unity.
Behaviour significa appunto “comportamento generico”. E’ grazie ad essa che avremo a disposizione i metodi: Start(), Update() ecc… Questi metodi sono fuzioni della classe MonoBehaviour.
Come descritto in panoramica su uno script in unity.
Avevo già provato a seguire altri corsi base, ma non erano riusciti a chiarirmi le idee. Tu invece sai entrare nella testa del principiante e sai come rendere comprensibili concetti nuovi e apparentemente complessi. Grazie davvero!
Ciao Laura,
si, quando si parla di poligoni si parla sempre di triangoli ovvero la superficie più piccola realizzabile su un modello 3D, una sola “faccia” comprende tre vertici e la superficie che ne riempie lo spazio.
sei veramente bravo a spiegare, e sto capendo come funziona il c#
complimenti
Grazie! 😉
Ciao, io sto ripassando la tua guida per la seconda volta, cercando di applicare più concretamente i concetti che spieghi. Io vorrei creare per gioco una funzione che se il numero è compreso tra 1 e 10 esegue una azione, ma quando tocca il dieci torna indietro fino all’uno. Mi spiego:
If (input.GetKey(Keycode.W))
{Dimensioneoggetto += Dimensione //Non ti metto io transform dell’oggetto, ma fa finta che vi sia
Dimensione = Dimensione + 1}
Fino a che l’oggetto non raggiunge una dimensione di 10 x 10 x 10. Dopodiché vorrei che tornasse indietro fino ad uno, e viceversa. In parole povere tengo premuto il tasto e l’oggetto si ingrandisce e poi diminuisce, pooi si ingrandisce e diminuisce e così via. Sto cercando, senza bazzicare sull’internet, di trovare quella funzione che mi permette questo.
Ciao, puoi usare un conteggio con un intero, inizializzato esternamente.
int i = 0;
DimensioneOriginaleOggetto = Dimensioneoggetto;
ogni volta che i raggiunge 9, resetti la dimensione dell’oggetto
If (input.GetKey(Keycode.W)) {
Dimensioneoggetto += Dimensione
Dimensione = Dimensione + 1
i++;
if (i >= 9){
Dimensioneoggetto = DimensioneOriginaleOggetto (che avrai opportunamente salvato)
i = 0;
}
}
Spero di essere stato chiaro. Ciao.
Ciao,
come ha suggerito fiortrackers puoi usare un aumento graduale, poi però non avresti il ritorno graduale alla dimensione originale.
Da quello che ho capito vuoi che al rilascio del pulsante la scala torni gradualmente alla dimensione originale.
Oppure anche tenendo premuto il tasto, una volta arrivato a 10 la dimensione dovrà degredire? Questo non mi è chiaro.
Comunque dovrai moltiplicare la scala dell’oggetto per un numero, poi sarà quel numero ad essere gestito in base alla pressione del tasto.
tipo:
float scaleMultipler=1;
void Update()
{
If (input.GetKey(Keycode.W)) //Se il tasto è premuto la scala aumenta
{scaleMultipler++;}
else //Se il tasto è rilasciato la scala diminuisce
{
scaleMultipler–;
}
//Moltiplico la scala per il valore Clampato, cioè impostato per avere un valore minimo e uno massimo, da 1 a 10
transform.scale*=Mathf.Clamp(scaleMultipler,1,10);
}
In linea teorica, dovresti fare una cosa del genere.
Se puoi vuoi regolare la velocità con cui si espande e cotrae la scala, invece che usare il ++ e il — (cha aumentano e diminuiscono di 1 ad ogni frame) dovrai aggiungere un moltiplicatore, tipo
….
{
scaleMultipler+=0.1F;
….
Sempre cha abbia capito cosa vuoi ottenere 😉
In questo modo, finché il tasto rimarrà premuto la scala aumenterà fino ad un massimo di X10 e anche mantenedolo premuto non andrà mai oltre.
Poi diminuirà (fino alla sua dimensione originale) solo al rilascio del pulsante.
In questo modo la scala sarà modificata in modo lineare, se invece volessi avere un aumento graduale dovresti usare un Lerp…
GG Prof !
Finalmente sono riuscito a capire il perché il mio script non funzionava : dopo la condizione di if mettevo ; che mi scatenava tutta una serie di errori che non riuscivo a correggere. Posso dire solo un grande grazie e, ti consiglio, di registrarti nei brave rewards, così che ti possa fare qualche donazione per aggiornare questi tutorial :-).
Ciao e grazie.
Non so cosa siano le rewards di Brave ma non sei il primo a darmi questo consiglio. Mi informerò.