Per prima cosa ci occorre uno sprite. Come abbiamo già fatto nelle lezioni precedenti salviamo l'immagine seguente e importiamola negli Assets del nostro progetto Unity.
Come per i pianetini, scegliamo la Sprite Mode multiple ed effettuiamo lo Splice automatico.
Il risultato finale sarà il seguente.
Trasciniamo lo sprite arcadia_0 appena creato nella scena di gioco e dopo averlo rinominato Arcadia modifichiamo il parametro Scale per ridurne le dimensioni.
Abbiamo creato nella scena di gioco la nostra astronave, vediamo quindi quali sono le funzionalità messe a disposizione da Unity per renderla un elemento di gioco e farla interagire con gli altri oggetti della scena.
Per prima cosa, in ogni gioco che si rispetti, il Player deve evitare di urtare gli oggetti pericolosi o i nemici in generale.
Per determinare se uno sprite entra in collisione con un altro, la prima cosa da fare è definirne i contorni. Questa operazione può essere effettuata in diversi modi, alcuni più precisi altri un po' meno. Ovviamente il vantaggio dei metodi meno precisi è che risultano elaborativamente più efficaci.
In questi ultimi in generale l'immagine viene approssimata ad un rettangolo o ad un cerchio circosritto od inscritto. Invece di verificare la collisione in maniera precisa (pixel per pixel), la collisione viene riscontrata solo se il rettangoli o i cerchi di collisione entrano in contatto. Questo modo di operare è molto efficiente, ma può dar luogo a sfioramenti tra sprite senza generazione di una collisione o viceversa a collisioni senza che vi sia un contatto. Nell'immagine seguente è mostrato il problema appena esposto. Utilizzando il rettangolo in blue come rettangolo di collisione, i due aerei sulla destra risultano toccarsi anche se distanti l'uno dall'altro.
Unity consente di definire tre tipi di collider: box collider, circle collider e polygon collider. I primi due sono dei collider approssimati, mentre il terzo crea una serie di poligoni che si avvicinano di molto alla forma esatta dello sprite.
Per aggiungere un collider alla nostra astronave premiamo il bottone Add Component del pannello Inspector, quindi Physics 2d -> Polygon Collider 2D.
Nell'immagine vediamo il risultato ottenuto. Le linee sottili verdi rappresentano i poligoni calcolati da Unity per calcolare le collisioni. Come possiamo vedere il risultato è molto accurato, anche se sarà particolarmente oneroso in termini di performance. Per il momento però non preoccupiamocene anche perché il tutto dipenderà da quanti oggetti di gioco entreranno a far parte della nostra scena.
Il Poligono Collider è un collider utilizzabile con la fisica 2D . La forma del collider è definita da un bordo a forma libera fatta di segmenti di linea , in modo da potersi adattare dello Sprite con grande precisione. Si noti che il bordo di questo collider deve racchiudere completamente un'area ( a differenza dell' Edge Collider 2D ) .
- Material - Specifica un materiale 2D. Il motore di fisica utilizza proprietà come l'attrito e il rimbalzo per calcolare gli effetti delle collisioni.
Il collider può essere modificato manualmente, ma spesso è più conveniente lasciare che Unity determini automaticamente la forma.
- Is Trigger - Se selezionato esclude la gestione delle collisioni dal motore di fisica e permette di gestirle tramite script.
È possibile modificare la forma del poligono direttamente tenendo premuto il tasto shift mentre si sposta il mouse su un bordo o vertice nella vista scena . È possibile spostare un vertice esistente facendo shift-click quando il mouse si trova sopra di esso. Se si effettua questa operazione non su un vertice, ne verrà creato uno in automatico. È possibile rimuovere un vertice tenendo premuto il ctrl/cmd e cliccando su di esso .
Il nostro Player adesso è in grado di urtate ed essere colpito dagli altri oggetti di gioco. Per completare il suo comportamento occorre quindi porlo sotto il controllo del motore di fisica aggiungendo il componente Rigidbody 2D.
Un componente Rigidbody 2D mette un oggetto sotto il controllo del motore fisico.
Masss - Massa del rigidbody .Linear Drag - Coefficiente di resistenza che si oppone al movimento lineareAngular Drag - Coefficiente di resistenza che si oppone al movimento di rotazione .Gravity Scale - L'accelerazione gravitazionale che agisce sul corpo. Il valore 1 è pari alla forza di gravità terrestre.Fixed Angle - Può il rigidbody ruotare quando si applicano forze?Is Kinematic - Può il rigidbody essere mosso dalle collisioni?Interpolate - Come interpolare il movimento dell'oggetto (utile quando il movimento tende ad essere a scatti ) Sleeping Mode - Permette di risparmiare potenza di calcolo quando l'oggetto è a riposo
Collision Detection - Come vengono rilevate le collisioni con altri oggetti.
L'aggiunta di un Rigidbody 2D permette ad uno sprite di spostarsi in un modo fisicamente convincente applicando delle forze tramite scripting. Quando il componente collider appropriato è anche collegato all'oggetto sprite, esso viene influenzato dalle collisioni con gli altri oggetti in movimento. L'utilizzo della fisica semplifica molte meccaniche di gioco e permette al gioco di essere realistico.
- Discrete Una collisione viene registrata solo se il collider dell'oggetto è in contatto con un altro durante un aggiornamento fisica.
- Continua Una collisione viene registrata se collider dell'oggetto sembra aver contattato un altro tra gli aggiornamenti .
L'impostazione cinematica spegne il comportamento fisico del Rigidbody 2D in modo che non reagisca alla gravità e alle collisioni. Questo è in genere utilizzato per mantenere un oggetto sotto il controllo degli script non fisici per la maggior parte del tempo, per poi passare alla fisica in una particolare situazione.
Nominiamo lo Script in PlayerScript e con un doppio click aprimao l'editor MonoDevelop e incolliamo il codice seguente.
Salviamo tutto e aggiungiamo lo Script appena creato all'astronave Arcadia.
using UnityEngine; ////// Controllo del Giocatore /// public class PlayerScript : MonoBehaviour { ////// La velocita' del Player /// public Vector2 speed = new Vector2(10, 10); // Spostamento del Player private Vector2 movement; // Larghezza ed altezza del Player private float spriteWidth ; private float spriteHeight ; void Awake() { // Calcolo della larghezza e l'altezza dell'astronave spriteWidth = renderer.bounds.max.x - renderer.bounds.min.x; spriteHeight = renderer.bounds.max.y - renderer.bounds.min.y; } void Update() { // Lettura del valore dei pulsanti di controllo del player float inputX = Input.GetAxis("Horizontal"); float inputY = Input.GetAxis("Vertical"); // Calcolo del vettore della velocita' movement = new Vector2( speed.x * inputX, speed.y * inputY); // Limitazione della posizione del Player all'interno dei limiti dello schermo (Camera) var dist = (transform.position - Camera.main.transform.position).z; var leftBorder = Camera.main.ViewportToWorldPoint( new Vector3(0, 0, dist) ).x; var rightBorder = Camera.main.ViewportToWorldPoint( new Vector3(1, 0, dist) ).x; var topBorder = Camera.main.ViewportToWorldPoint( new Vector3(0, 0, dist) ).y; var bottomBorder = Camera.main.ViewportToWorldPoint( new Vector3(0, 1, dist) ).y; transform.position = new Vector3( Mathf.Clamp(transform.position.x, leftBorder + (spriteWidth/2), rightBorder - (spriteWidth/2)), Mathf.Clamp(transform.position.y, topBorder + (spriteHeight/2), bottomBorder - (spriteHeight/2)), transform.position.z ); } void FixedUpdate() { // Spostamento del Player rigidbody2D.velocity = movement; } }
A questo punto lanciamo il gioco in esecuzione e facciamo un po' di pratica di pilotaggio.
inserisco lo script ma mi da errore in "bounds" not declared e "velocity" .... che faccio?
RispondiEliminaspriteWidth = GetComponent().bounds.max.x - GetComponent().bounds.min.x;
EliminaspriteHeight = GetComponent().bounds.max.y - GetComponent().bounds.min.y;
GetComponent().velocity = movement;
prova così.
quando inserisco lo scipt mi da errore: Assets/Scripts/PlayerScript.cs(7,0): error CS1525: Unexpected symbol `{'
RispondiEliminaporco dio pure a me trova la soluzione madonna cane
EliminaSpiegazioni fino a qui molto chiare. lo script "Playerscript" funziona perfettamente se copiato in toto (versione Unity 2021.1.13f1). L'effetto gravitazionale del componente Rigidbody 2D andrebbe resettato a zero in quanto nello spazio "libero" ha davvero poco senso. Grazie mille!
RispondiElimina