Il 0% ha trovato utile questo documento (0 voti)
107 visualizzazioni20 pagine

1 - Unity 3D e 2D, C#

lessons
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
107 visualizzazioni20 pagine

1 - Unity 3D e 2D, C#

lessons
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 20

Sviluppare con Unity

2D e 3D
Scripting in C#

A cura di Federico Bachis, [email protected]


In questa lezione:

1. Scripting
2. Fondamenti di programmazione a Oggetti
3. Eventi base del ciclo di vita di Unity
4. Come leggere un input
5. Best-Practice e Naming Convention
File e prerequisiti per la lezione
Scaricate questo zip e estraetelo, contiene uno UnityPackage. Aggiustiamo i materiali in maniera semplice.
Gli UnityPackage contengono asset per i progetti Unity, potete importarlo
sul vostro progetto corrente aperto facendo doppio click o trascinandolo sul Nella finestra project, individuate la cartella materials e
project. selezionate tutti i materiali danneggiati (in rosa).
Selezione multipla con Maiusc + click del primo e
Una finestra di importazione vi permetterà di scegliere quali file includere. dell’ultimo elemento oppure Ctrl + A per selezionarli tutti.
Andate su:
Aprite la scena Prototype 1, vedrete che i materiali sono danneggiati. Edit>Rendering>Materials>Convert Selected Built-in
La versione di questo package utilizza la vecchia Built-In Render Pipeline. Materials to URP
C#: Hello world!
Il linguaggio di programmazione usato da unity è C#
Permette di creare la logica di gioco, controllare il
comportamento dei GameObject e gestire eventi.
Gli script creati sono components e possono essere
assegnati ai GameObject, gestendo input, fisica,
animazioni e molto altro.

Gli script C# in Unity derivano dalla classe MonoBehaviour, che fornisce metodi chiave
come Start() e Update() per gestire eventi nel ciclo di vita del gioco.

Monobehaviour Unity Life Cycle


OOP, ovvero Object Oriented Programming
Il C# è un linguaggio orientato agli oggetti. Cioè è proggettato per organizzare il
codice intorno a entità chiamate oggetti.
Alcuni concetti fondamentali:
● Tipi (int, bool, float, string)
● Variabili
● Classi
● Istanze
● Metodi
● Firme
● Ereditarietà
Le variabili
Una variabile è un contenitore di informazioni, è composta da 4 elementi:

● Modificatore di accesso: public o private, determina se è accessibile dall’esterno della classe in cui
risiede
● Tipo dell’informazione che contiene può essere un tipo base (int, float, char o bool) oppure una
classe (Vector3, GameObject, Transform etc)
● Nome: arbitrario, ma scelto in maniera da esplicitare il contenuto (counter, speed, movement)
● Valore: può essere un valore numerico(es. 42), una stringa (es. “hello world”) o un riferimento a
un’istanza di classe (es. un transform, un rigidbody, un gameobject o altro).

Una variabile ha 2 fasi fondamentali: la dichiarazione e l’inizializzazione.

● La dichiarazione comprende il modificatore di accesso, il tipo e la scelta del nome:


public int counter; //Dichiara una variabile pubblica, di tipo intero, chiamata counter
● L’inizializzazione è l’assegnazione di un valore a una variabile che sia stata dichiarata:
counter=0; //Assegna il valore 0, alla variabile chiamata counter
● Potete fare la dichiarazione e l’inizializzazione in una sola riga di codice:
public int counter = 0; //Dichiara una variabile pubblica di tipo int, chiamata counter, con valore 0
I Tipi
I tipi possono essere divisi in tipi di base e in tipi complessi
● Tipi base che ci interessano sono numeri decimali (float), numeri
interi (int), booleani (bool), caratteri (char) e gruppi di caratteri
(string).
Questi tipi rappresentano una singola informazione, di un singolo
tipo appunto.
● I tipi complessi invece sono in grado di rappresentare più
informazioni dello stesso tipo (Vector3 rappresenta 3 float), o di tipi
diversi (Transform rappresenta 2 Vector3 scala e posizione e un
Quaternion per la rotazione)
Differenza tra classe e istanza
Una classe è un tipo complesso, è un modello in grado di organizzare dati (chiamati attributi o
proprietà) all’interno di variabili e comportamenti (chiamati metodi).

L’istanza è un oggetto di una certa classe, in cui le variabili sono state inizializzate.

Per ogni classe possono esistere molte istanze.


Possiamo salvare il riferimento di una istanza di classe su una variabile del tipo opportuno.

Per esempio se definiamo una classe Room, potremmo avere l’istanza kitchen, studio o office.
Ogni Room sarà caratterizzata da valori delle variabili diversi (areaSize, doorsNumber,
windowNumber) e da metodi comuni (GoInside, Explore, GoOut ecc)

public Room currentRoom = office; //Assegna alla variabile chiamata currentRoom di tipo Room
il riferimento all’istanza office.
Metodi, firme e visibilità
Un metodo è una porzione di codice che si occupa di eseguire una certa azione.

public void Move(Vector2 input){ //corpo}


public void Jump(){//corpo del metodo}
public bool Shoot(){//corpo del metodo}

Un metodo può richiedere dei parametri.


ad esempio Move(input);
L’insieme del nome e dei parametri costituisce la firma di un metodo.

La firma deve essere univoca, il nome invece può essere usato più volte, in questo caso si dice che il metodo
è overload, ad esempio Move(Vector2 position) e Move(Vector3 position) possono coesistere perchè la loro
firma è differente, sarà il tipo di parametro ricevuto dal metodo a determinere quale chiamare.

● il modificatore di accesso determina dove può essere usato il metodo


● il tipo di ritorno, determina il tipo del risultato dell’operazione
● il nome del metodo servirà a usare/chiamare il metodo
● I parametri sono i valori su cui eseguirà i calcoli
Ereditarietà e interfacce, in breve
//Esempio di ereditarietà:
Una classe può ereditare metodi e variabili da un’altra classe ed estendere le class Cane : Animale
sue proprietà e il suo comportamento base, indichiamo che una classe eredita { … }
da un’altra con i due punti : /*La classe Cane eredita da Animale o estende la
classe Animale.
Potete sempre usare una classe derivata dove è richiesta una classe base La classe Animale è detta la classe base di Cane.
(Polimorfismo). La classe Cane è detta classe derivata o figlia.*/

Le interfacce in C# definiscono un contratto: specificano quali metodi e //Esempio di contratto


proprietà una classe deve implementare, senza fornire un'implementazione. class Enemy : IDamageable, IHealable
Una classe può implementare più interfacce, permettendo una maggiore
{ /*Deve implementare TakeDamage e Heal*/}
flessibilità e supporto al polimorfismo.
public interface IDamageable
● Ereditarietà: riuso di codice e specializzazione tramite una classe {
base. void TakeDamage(int damage);
● Interfacce: definizione di un contratto che le classi devono seguire, }
favorendo la flessibilità. public interface IHealable
Le classi possono ereditare i metodi e le variabili di una sola classe, ma {
possono implementare tutte le Interfacce che si vuole, per farlo si usano void Heal(int healAmount);
sempre i 2 punti e si separano le diverse interfacce con la virgola. }
La classe MonoBehaviour
Un MonoBehaviour è la classe base di Unity, tutti gli script che interagiscono con il
motore di gioco ereditano da MonoBehaviour.
I nuovi script creati in Unity sono pre-configurati per derivare da MonoBehaviour.
Questa classe ci permette di usare le callback di sistema di Unity, che sono alla
base del life-cycle dei nostri giochi.

Principali callback di sistema:

● Awake() //Chiamato una volta quando l'oggetto viene creato.


● Start() //Chiamato una volta prima del primo frame.
● Update() //Chiamato ad ogni frame, utile per aggiornamenti regolari.
● FixedUpdate() //Chiamato a intervalli regolari di tempo è usato dalla fisica.
● OnDestroy() //Chiamato quando l'oggetto viene distrutto.
Awake, Start e OnEnable Script di test
Awake viene eseguito una volta sola, quando il GameObject che lo contiene viene inizializzato,
indipendentemente dallo stato di abilitazione dello script.
Il game object che lo ospita invece deve essere attivo.
OnEnable Chiamato ogni volta che il componente viene attivato.
Start viene eseguito una sola volta dopo che tutti gli Awake sono
stati eseguiti, inclusi quelli degli altri script.
Viene chiamato solo se il GameObject e il componente sono attivi.
Nessuno di questi viene chiamato se il GameObject è disattivo.
Non confondete i components e i GameObject.
Inizializzate i valori delle variabili su Awake ma non le dipendenze, eventualmente le dipendenze
andranno su Start. Spesso vogliamo riciclare un oggetto, disattivandolo e riattivandolo, piuttosto che
distruggerlo e ricrearlo, in quel caso l’inizializzazione andrà su OnEnable.
Update, LateUpdate e FixedUpdate
Update, è chiamato una volta per ogni frame, è quindi influenzato dal frame rate

LateUpdate, è chiamato una volta per frame, dopo che l'Update termina la sua
esecuzione, anche questo è influenzato dal frame rate.

FixedUpdate, è chiamato a intervalli regolari di tempo (Per quanto possibile). Può


essere eseguito più o meno spesso dell'Update, ma non dipende dal framerate.

Il contenuto di questi metodi è un loop, ovvero un ciclo, significa che il codice al


loro interno verrà ripetuto nuovamente, una volta completato
Naming conventions in C#
Nomi parlanti: Preferite sempre nomi auto-esplicativi a nomi brevi per variabili metodi e classi.
es. totalAmmount ✓ tA✗
PascalCase: per il nome delle classi, dei metodi e delle costanti. es. MyClass, MyMethod, MyCostant
IPascalCase: Per le Interfacce iniziate con la lettera I maiuscola. es IHealable, IDamageable
camelCase: per i parametri dei metodi e per le variabili. es. fireRate, TakeDamage(int damage)
_camelCase: per le variabili private iniziate con un underscore _
s_camelCase: per le variabili statiche iniziate con s e underscore s_
Le Naming Conventions hanno lo scopo di rendere il più chiaro, ordinato e comprensibile il codice a
chi lo legge.
Il codice funziona anche se non le rispettate Cercate di rispettarle!
Oltre a queste regole è utile utilizzare i commenti all’interno del codice. // /**/ ///
Modificatori
Modificatori di Accesso Modificatori di Classe e metodo

● public: La classe o il membro è accessibile da ● static: I valori statici appartengono alla classe
qualsiasi altra classe o codice. anziché a una specifica istanza.
● private: La classe o il membro è accessibile solo
● virtual: Indica un metodo che può essere sovrascritto
all'interno della propria classe.
● internal: valore di default, renderà la classe o il dal modificatore override. I metodi virtual possono
membro accessibile all'interno dello stesso avere un'implementazione predefinita.
assembly. ● override: Sovrascrive un metodo ereditato che è
dichiarato come virtual o abstract nella classe base
……………………………………….
……………………………………….
● protected: La classe o il membro è accessibile
all'interno della propria classe e nelle classi ● abstract: Classe che non può essere istanziata
derivate.
direttamente o metodo che deve essere
● protected internal: La classe o il membro è
accessibile sia all'interno dello stesso assembly implementato nelle classi derivate.
che nelle classi derivate, anche se si trovano in Le classi astratte possono contenere solo metodi
assembly diversi. astratti.
● sealed: Classi che non possono essere estese
Sintassi: Dotted notation e punto e virgola
In C# se volete leggere il parametro di un oggetto o usare un suo metodo, dovete
usare la dotted notation, ovvero:
● nomeOggetto.nomeVariabile;
● nomeOggetto.NomeMetodo();
● NomeClasse.NomeMetodoStatico();
Ogni linea di codice termina con il punto e virgola, non con l’andata a capo.
Le variabili andrebbero dichiarate e inizializzate all’inizio della classe:
modificatoreDiAccesso tipo nomeVariabile = valore o istanza;
public int counter = 0;
public float speed = 3.5f;
Istruzioni e operatori booleani
● if(condition){task1}else{task2} //Esegue task1 se la condizione è vera, task2 se è falsa *if else
● var a = condition ? value1 : value2; //Assegna value1 se la condizione è vera, assegna value2 se è falsa *Operatore ternario
● while(condition){task} //Esegue task sino a quando condition è vera, potrebbe non eseguirlo *Ciclo while
● do{task}while(condition); //Esegue task almeno una volta e lo ripete finchè condition è true *Ciclo do while
● foreach(item in items){task} //Per ogni elemento item in una lista ripete task *Ciclo foreach
● for(int i=0; i<n; i++){task} //Svolge task n volte a ogni esecuzione incrementa i di 1 unita *Ciclo for
● for(;condition;var++){task} //Svolge task sinchè condition è vera a ogni esecuzione incrementa var *Ciclo for
● return; o return value; //Termina l'esecuzione di un metodo e restituisce un valore

condition è un booleano, ovvero vale True o False e può essere il risultato di un’operazione, oppure una variabile di tipo bool.

Le operazioni che restituiscono booleani si fannoc con operatori di confronto e operatori logici

● (a > b), (a >= b) //a è Maggiore di b, a è Maggiore o uguale di b


● (a < b), (a <= b) //a è Minore di b, a è Minore o uguale di b
● (a == b), (objA.Equals(objB);) //a è Uguale b, objA è lo stesso oggetto di objB
● (a != b), (!objA.Equals(objB);) //a è Diverso da b, objA non è lo stesso di objB
● (condition1 && condition2) //Vero se condition1 e condition2 sono vere entrambre, falso altrimenti
● (condition1 || condition2) //Vero se condition1 è vera oppure se condition2 è vera, falso se entrambe sono false
La Documentazione
● Il manuale
● Le scripting API (Application
Programming Interface)

Altre risorse per iniziare:

● Tutorial in italiano per argomento


● Youtube e in particolare
● Brakeys
● Code Monkey
● Google, imparate a scrivere
ricerche che individuano subito il
problema.
● eBook
CarController.cs
Esercizio. Spostamento con velocità 𝑝𝑖+1=𝑝𝑖+𝑣∙Δ𝑡 o istantaneo 𝑝𝑖+1=𝑝𝑖+Δ𝑝
1. Muovere il transform in avanti a velocità costante, usare il Time.deltatime
2. Semplificate il collider del veicolo. Aggiungete la gravità al veicolo.
3. Create degli ostacoli fisici su cui il veicolo vada a scontrarsi.
4. Trovare la documentazione ufficiale sull’input.
5. Muovere il veicolo con l’input. (avanti e indietro)
6. Muovere il rigidbody anziché il transform applicando una forza.
7. Seguire il veicolo con la MainCamera
8. Fare ruotare il veicolo
Video sui modi per muovere un oggetto.
Ricordi tutti i termini usati?
● Asset ● IDE ● API
● Unity Package ● SOLID ● Naming Convention
● Pipe-Line ● Single Responsibility Principle ● Dotted notation
● URP ● Awake ● Dichiarazione
● Built-In PipeLine ● OnEnable ● Inizializzazione
● OOP ● Start ● if(c){}else
● C# ● Update
● Life Cycle ● Time.DeltaTime
● Tipi (int, bool, ● LateUpdate
float, string) ● FixedUpdate
● Variabili ● Commenti
● Classi ● Modificatori di classe
● Istanze ● Modificatori di accesso
● Metodi ● Loop
● Firme

Potrebbero piacerti anche