Imparare C#Principianti

Prime definizioni dei concetti base

Iniziamo a fare sul serio! Unity ci mette a disposizione di una ricca interfaccia con cui inserire oggetti nella scena, ma questo non basta. Dovremmo scrivere da noi il comportamento di tali oggetti. In questa sessione vi darò una prima infarinatura su cosa significhi la programmazione ad oggetti.

Accenni sulla Programmazione ad oggetti

Badate bene di non fare confusione. La parola oggetti in questo caso non ha nulla a che fare con i gameObjects di Unity. Stiamo parlando di oggetti "aleatori", cioè senza consistenza, del semplice testo di uno script in C#, non dei gameObject di Unity che sono gli oggetti di gioco posti fisicamente in uno spazio 3D, tutt'altra cosa.


Accenni informativi sul C#
Quello che impareremo infatti non sarà solo "programmare genericamente " ma specificatamente programmare "ad oggetti", sistema ormai utilizzato dalla maggior parte di linguaggi di alto livello che permette una maggiore semplicità di comprensione e velocità di scrittura. Il C# è una derivazione del C++ e ne eredita molte caratteristiche. Quando nacque il C++ (direttamente dal C) era inizialmente chiamato "C con classi" perché appunto era un'estensione del C con l'aggiunta di un sistema di programmazione ad oggetti. Abbiamo ripetuto più volte la terminologia di programmazione orientata ad oggetti e non a classi. In realtà sarebbe stato comunque corretto chiamare questo sistema "programmazione orientata a classi". Ma cerchiamo di non far confusione perché le classi non sono la stessa cosa degli oggetti. Potremmo paragonare una classe ad una categoria di oggetti.  


Le Classi

Un oggetto fa parte di una classe così come la mia BMW fa parte della classe "automobili". Il mio cane fa parte della classe "animali". Tu ed io facciamo parte della classe "umani".

Il concetto di classe rappresenta la funzionalità più importante del
linguaggio C++ e quindi, di tutti i linguaggi a esso simili, come il C#.

Una classe è, in parole semplici, una porzione di codice che identifica un oggetto.
Nel nostro caso, ogni script rappresenta una classe. Dunque, quando scriveremo un nuovo file .cs, avremo creato una nuova classe.

Per avere un'idea immediata di cosa sia una classe possiamo usare come esempio il fatto che tutte le cose sono riconducibili a determinate classi (per esempio: macchine, piante, animali ecc..). Delle categorie.
Tu, fai parte della classe "umani", il tuo gatto fa parte della classe "animali" ecc..
Tu sei un "oggetto", il tuo gatto è un altro oggetto facenti parte di classi diverse.
Tuo fratello fa parte della classe umani così come te e molti altri ma sono diversi tra loro per alcune caratteristiche, ovvero da alcune variabili.

Nel caso della programmazione di un gioco, un alieno, per esempio, potrà far parte della classe "nemici", un personaggio non giocante potrà far parte della classe "NPC", una pistola farà parte della classe "armi" e così via.
Ognuno di questi oggetti possiede delle variabili che la differenziano da un altro oggetto della stessa classe.

Due oggetti della classe nemici (sempre per esempio)  potranno differenziarsi tramite le variabili, energia, velocità, forza ecc... Un nemico più piccolo potrà avere come variabile energia = 10. Un nemico più grande avrà come variabile energia = 30. Entrambi sono della classe "nemici" ma nel gioco saranno degli oggetti diversi, perché gli imposteremo ad ognuno delle variabili diverse.




  L'esempio della palla

Prendiamo per esempio un oggetto della vita reale che conosciamo tutti: una normale palla.
Una palla possiede le sue caratteristiche specifiche, il peso, il colore, il materiale, ecc.. che sarebbero le sue variabili.
Tali variabili definiscono il comportamento della palla e la differenziano da un'altra palla.
Ed ha i suoi "metodi" cioè i suoi modi di interagire con l'esterno, tipo il rimbalzo, la velocità con cui rotola se calciata...
Tali metodi dipendono dalle variabili di cui sopra, se per esempio la "variabile peso" valesse 50 grammi, l'azione di rimbalzo produrrà determinati movimenti, diversi se il suo peso valesse  100 grammi.
Dunque avremmo due oggetti della stessa classe ma con caratteristiche (variabili) diverse e dunque comportamenti (metodi) diversi. Stessa classe ma oggetti e comportamenti differenti.
Se volessimo creare un'altra palla, con caratteristiche diverse da quelle di prima, dovremo creare un nuovo oggetto della " classe palla" ed assegnargli delle variabili differenti da quelle di prima.

Le variabili possono essere di tanti tipi diversi. Vedremo nel dettaglio i primi quattro tipi di variabili più comunemente usati in Unity, tra poco.





I Metodi (o Funzioni)

Un "metodo" è un blocco di codice all'interno di una classe che esegue una elaborazione e che in pratica "può far fare qualcosa" agli oggetti di quella classe quando il metodo è richiamato ed eseguito.

Il termine metodo è l'equivalente del termine funzione di altri linguaggi di programmazione.
Una funzione (o metodo) è una porzione di codice che viene richiamata tramite il suo nome e che quando eseguito, fa "succedere qualche cosa" .

Un esempio di metodo potrebbe essere:

void Spara()
{
    
}

dove il codice necessario sarà inserito all'interno delle parentesi graffe (chiamate scopo).

Allo stesso modo avremmo potuto scrivere in questo modo:

void Spara() 
{ }

oppure

void Spara() { }

a dimostrazione che si può scrivere il codice in modo più o meno ordinato senza comprometterne il funzionamento.

Per eseguire un metodo sarà poi sufficiente richiamare il suo nome, senza specificare la parola void.
Per esempio:
Spara();
Che, se messo all'interno di un altro metodo che riceve l'input di un pulsante premuto diviene:

void PulsanteFirePremuto()
{
    Spara();
}

Ovvero, alla pressione del tasto Fire, verrà eseguito il metodo Spara();

Riassumendo:
un metodo si dichiara così:

void MioMetodo(){    }

e si esegue così:

MioMetodo();

 
Ma cos'è quella parolina "void" davanti al nome del metodo?
E le due parentesi tonde dopo in nome del metodo, che ci stanno a fare???

Essendo un metodo un "pezzo di codice che fa qualcosa quando eseguito", potremmo fare in modo che un esso restituisca il risultato dell'operazione che abbiamo fatto al suo interno. Ma questo non è sempre necessario. Infatti, nel caso in cui il metodo non debba restituire nulla, useremo proprio la parola void davanti ad esso. VOID significa appunto "vuoto".
La maggior parte dei metodi che useremo all'inizio non dovranno restituire nessun valore, dunque avranno la parolina void davanti.

Così come la parola prima del nome del metodo serve a far uscire "qualcosa dal metodo", allo stesso modo, le parentesi dopo il nome servono per "immettere dati" all'interno del metodo sotto forma di variabili. Queste variabili d'immissione vengono chiamate "parametri del metodo" perché appunto, esse sono dei valori che vengono immessi all'interno del metodo nel momento in cui lo eseguiamo. Nella maggior parte dei casi, almeno agli inizi, esse saranno vuote perché non dobbiamo spedire nessun parametro al metodo. Vedremo poi nel dettaglio quando e come farlo, se necessario.
Per esempio:

void Spara(int dannoProiettile) { }

Dove, quando dovremmo eseguire il metodo Spara, dovremmo spedire anche il valore che rappresenta il danno del proiettile (in questo caso, una variabile int, un numero intero).
In questo modo potremmo variare il danno dello sparo a nostro piacimento, ad ogni sparo, magari a seconda dell'arma in possesso del giocatore.




Facciamo un esempio con il codice C# della classe "Palla".

Vediamo come sarebbe scrivere in C# una classe (semplificata) di tipo Palla che possiede due metodi e due variabili.

public class Palla {

    public int pesoPalla;
    public int attritoPalla;
    

	void Rimbalzo () {
		//dai una spinta verso l'alto di 100 - pesoPalla
	}
	
	void Rotolamento () {
		//dai una spinta di rotazione alla palla di 100 - attritoPalla
	}
}


pesoPalla
e attritoPalla sono due variabili.
Rimbalzo e Rotolamento sono due metodi.

Abbiamo assegnato alla classe Palla due variabili, il peso e l'attrito.
La parola int d'avanti alle variabili determina il tipo della variabile, ovvero, in questo caso vuol dire che quelle due variabili sono di tipo "numeri intero". Dei normai numeri che specificano il peso.
La parola public sta ad indicare che si tratta di variabili pubbliche, cioè che saranno accessibili da altri scripts e visibili e modificabili nell'inspector di Unity.

Inoltre ci sono due metodi, uno per il rimbalzo e uno per il rotolamento.
Dentro alle parentesi graffe dei metodi scriveremo il codice per fargli fare ciò che vogliamo che faccia, in caso di rimbalzo e in caso di rotolamento.  In questo esempio abbiamo solo scritto del testo che faccia capire come potrebbe
funzionare un metodo. In realtà in questo esempio lo script non fa niente di particolare essendoci all'interno dei metodi, solo commenti e non del codice da eseguire. Ma noi ci serve per capire il funzionamento dei metodi.

Come si può notare, abbiamo fatto in modo che il rimbalzo dipenda dal peso della palla e che il rotolamento dipenda
dall'attrito.
A seconda del peso la palla effettuerà un rimbalzo più o meno alto e rotolerà a seconda del suo attrito.
Se per esempio la palla pesasse 90, la spinta del rimbalzo sarebbe di 10 perché gli abbiamo detto che la forza del rimbalzo deve essere di 100 meno il suo peso.
Allo stesso modo la palla rotolerà più velocemente se il suo attrito sarà minore perché abbiamo deciso che la spinta di rotazione dovrà essere pari a 100 meno il suo attrito. Se per esempio il suo attrito fosse di 70, la spinta di rotazione sarà di 30.
Basterà dunque assegnare questo script a dei un gameObjects nella scena di Unity e tramite l'inspector assegnare i valori che vogliamo alle due variabili.

Approfondiremo il concetto di classe, metodi e variabili nelle lezioni a venire. Per ora ci limiteremo alle conoscenze base, il loro utilizzo diverrà automatico solo dopo pochi esercizi.

Dunque, ogni oggetto ha le sue caratteristiche che chiameremo variabili e i suoi modi di interagire, (le funzioni che dovrà fare), che chiameremo metodi o funzioni.

Se per esempio scrivessimo la classe "nemico.cs" e applicassimo lo script a  tanti gameObject che rappresentano i nemici in una scena, avremmo ottenuto tanti oggetti appartenenti ad una sola classe con i suoi  metodi per "funzionare".

Riassumendo sui metodi

  • I metodi si richiamano tramite il loro nome. Se non richiamati, i metodi non fanno assolutamente nulla, non vengono eseguiti. Non basta che un metodo si trovi in uno script, esso deve essere eseguito per funzionare.
  • Gli unici metodi che vengono eseguiti automaticamente sono alcuni metodi di Unity, tra i quali:
    Start() (eseguito all'apertura della scena),
    Update() (eseguito ad ogni fotogramma del gioco).
    Vedremo i metodi integrati di Unity più avanti in questa lezione.
  • Nota: In Unity un metodo presente su uno script può essere eseguito solo se lo script (e il gameObject su cui è posizionato) è attivo.

Primi approfondimenti sulle variabili

Brutto nome? Da la sensazione di essere un concetto difficile? Si tratterà di qualche complicato concetto matematico da cervelloni?
Ed invece, le variabili sono la cosa concettualmente più facile da capire, indispensabili in ogni linguaggio di programmazione.

Una variabile è, come dice la parola stessa, una cosa che varia. Tutto quì.
Mettiamo per esempio che stiamo giocando con un gioco di corse automobilistiche, avremo la velocità con cui andiamo, il punteggio che stiamo ottenendo, la posizione con cui ci piazzeremo e molte altre..variabili. Queste sono tutte variabili numeriche. Esistono diversi tipi di dati, dunque di variabili, come per esempio variabili di tipo testuale, numerica, ecc...

Per rendere più chiaro il concetto di variabile, potremmo prendere come esempio un contenitore e il suo contenuto che chiameremo valore.


Nel nostro caso il bicchiere è la variabile e "Evviva il C# e Unity!" è il valore .

Su uno script in C# la definiremmo così:

string bicchiere = "evviva il c# e Unity!";

Dove:

  • string è il tipo di variabile
  • bicchiere è il nome della variabile
  • "evviva il c# e Unity!" è il valore della variabile.

Il punto e virgola finale identifica la fine dell'operazione.

 


Riassumendo sulle variabili

Alcune terminologie basilari:

Dichiarare una variabile

Vuol dire "creare" una variabile, senza assegnargli per forza un valore:

int mioNumero;

 
In pratica si "avverte" il programma dicendogli: "sappi che userò una variabile chiamata mioNumero, ti tipo int (numero intero)".
Sarà così riservata una parte di memoria per il suo uso.

Inizializzare una variabile

Vuol dire assegnare un valore iniziale alla variabile:

mioNumero = 2;

Dichiarare e Inizializzare una variabile

 Vuol dire assegnare un valore inziale ad una variabile nello stesso momento della sua creazione:

int mioNumero = 2;



Una variabile viene prima di tutto dichiarata (scritta al di fuori di ogni metodo), ovvero scritta dentro lo "scopo" (le parentesi graffe) della classe:

public class Palla { //Apertura classe Palla
    
    int mioNumero; //Dichiaro la variabile (ma non la inizializzo)
    
      void Start() //Metodo Start (vuoto)
    {
        
    }
    
}

Una variabile può essere letta e modificata (ovvero ci si può lavorare) solo all'interno di un metodo:

public class Palla { //Apertuta della classe
    
    int mioNumero; //Dichiaro la variabile
    
    void Start() //Metodo Start
    {
        mioNumero = 10 + 20; //Lavoro con la variabile all'interno del metodo Start
        
    }// Chiusura metodo Start
    
}//Chiusura Classe
    

Una variabile può essere dichiarata anche all'interno di un metodo, ma in quel caso sarà "visibile" e gestibile solo all'interno di quel metodo:

public class Palla { //Apertura della classe
    
    void Start() //Metodo Start
    {
       int mioNumero; //Dichiaro la variabile all'interno del metodo Start
       
    }//Chiusura metodo Start
    
    void AltroMetodo() //Metodo AltroMetodo
    {
        
        mioNumero=20; //Questa riga riporterà un errore, mioNumero non esiste in questo contesto
   
    }//Chiusura AltroMetodo
    
}//Chiusura Classe
    

Una variabile può essere inizializzata anche nel momento della sua dichiarazione, anche al di fuori di un metodo:

public class Palla { //Apertura della classe Palla
    
    int mioNumero = 10; //Dichiarazione e inizializzazione della variabile
    
}// Chiusura della classe Palla

Approfondiremo la questione variabili in una: apposita sessione sulle variabili.

Conclusioni finali

Confusi?
Non vi allarmate, questi concetti sono a scopo informativo, necessari per l'apprendimento del mondo della programmazione e trovarsi più avvantaggiati in futuro.
In realtà con Unity potrete anche creare il vostro primo gioco senza neanche conoscere la definizione corretta di classe o oggetto. Sta a voi approfondire l'argomento, se ne avrete voglia.
Sarà però di fondamentale importanza aver compreso correttamente il funzionamento dei metodi e delle variabili di cui non si può fare a meno.
Ma non scoraggiatevi se non avete ancora capito questi fondamentali. Queste lezioni puramente teoriche sono il primo passo verso la comprensione di certi meccanismi che vi verranno automatici dopo i primi test partici.

7 pensieri su “Prime definizioni dei concetti base

  1. ciao, grazie per queste guide…
    Se ho ben capito la lezione ci sarebbe un piccolo errore di battitura da correggere.
    Quando fai il primo esempio del codice sul peso e sulla forza di rotazione della palla
    “void Rotolamento () {
    //dai una spinta di rotazione alla palla di 10 – attritoPalla”
    avrebbe dovuto essere :
    “void Rotolamento () {
    //dai una spinta di rotazione alla palla di 100 – attritoPalla”
    giusto?
    Grazie, se cosi non fosse devo rileggere l’articolo 🙂

    1. Hai ragione! 😉
      Anche se si tratta di un esempio in cui la forza può essere variabile. Ma secondo l’esempio che ho descritto successivamente è giusto 100-attrito.
      Grazie della segnalazione, correggo.

  2. Sto seguendo le lezioni dall’inizio pur avendo delle conoscenze di programmazione, fino ad ora tutto ben fatto, davvero un ottimo lavoro.

    1. Grazie! 😉
      Non è semplice trovare il giusto metodo di siegazione che non spaventi i neofiti che dunque implichi un compromesso tra l’approfondimento di un argomento complesso e la semplicità di approccio ad esso.

Rispondi a WILEz Annulla risposta

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