In questa lezione analizzeremo i prefab, ovvero i 'blocchi di costruzione' di Unity, utili per riciclare oggetti che compaiono più e più volte in scena.
I Prefab
I prefab (abbreviazione che sta per 'prefabbricati') sono un tipo speciale di asset, che non viene importato ma creato dentro Unity. Sono essenzialmente dei GameObject che vengono salvati nel progetto (e non solo in una scena, come tutti gli altri), per poi essere riutilizzati in diverse situazioni. Chi ha familiarità con Flash può pensare ai prefab come agli oggetti di libreria.
Di fatto, i prefab sono utili ogni volta che un oggetto deve comparire più di una volta, e deve avere caratteristiche simili. Ogni volta che un prefab viene messo in scena, si dice che quella è un'istanza del prefab stesso.
Il rapporto fra le Istanze ed i Prefab
Ho scritto caratteristiche 'simili' e non 'uguali', perché un'utile proprietà dei prefab in Unity (ma anche quella che genera molta confusione se usata male) è che i prefab hanno delle caratteristiche proprie che vengono riportate nelle istanze, ma a discrezione dello sviluppatore alcune istanze potrebbero differire in una o più di queste caratteristiche, pur rimanendo legate al prefab 'padre'. Vediamo un esempio pratico.
Create un cubo in una scena vuota (GameObject > Create Other > Cube
). Questo è un semplice GameObject, e tutte le modifiche che possiamo fargli rimarranno solo su di lui.
Trascinate il cubo dal pannello Hierarchy a quello Project. Verrà creato un nuovo prefab a partire dal cubo in scena. Il cubo nella scena ora è un'istanza di questo prefab, ed infatti il suo nome nella Hierarchy ora appare in blu.
È importante capire che tutte le modifiche apportate al prefab nel pannello Project, vengono applicate a tutte le istanze del prefab in tutte le scene del gioco, a meno che la proprietà modificata non sia stata già modificata nell'istanza stessa, cosa che la rende indipendente dal prefab.
Rinominate il primo cubo in scena in Cube1
, duplicatelo (Ctrl+D
), rinominate il secondo come Cube2
e spostatelo un po' in modo che non siano sovrapposti. Ora abbiamo due istanze del prefab Cube
.
Selezionate il prefab Cube
nel pannello Project (non le istanze nella Hierarchy!) e cambiate la scalatura Y da 1
a 4
. Le due istanze in scena assumono scala 4
, proprio come il prefab padre.
A questo punto, i due cubi sono identici al prefab. Selezionate Cube2
dalla Hierarchy o dalla Scene View, e cambiatene la scala Z a 3
. Notate come il testo all'interno del campo nell'Inspector venga evidenziato in grassetto, a simboleggiare che ora questo valore è slegato da quello del prefab padre.
In realtà, è possibile notare come anche l'intera riga position (x, y, z) sia in grassetto. Questo perché nello spostare Cube2
subito dopo aver duplicato Cube1
abbiamo slegato la sua posizione da quella del prefab padre.
In ogni caso, è logico che posizione e rotazione delle istanze siano sempre slegati da quelle del prefab, altrimenti non si potrebbero comporre scene con oggetti che hanno tutti la stessa posizione!
A questo punto, la scalatura Z di Cube2
è slegata da quella del padre.
Modificate la scala del prefab dal pannello Project, portando tutti e tre i valori ad 1. I due cubi si abbassano, e Cube1
ridiventa un cubo perfetto. Cube2
però, si riduce in altezza, ma la sua scala Z (che ora è indipendente) rimane 3, rendendolo un parallelepipedo come nella figura seguente:
Il pannellino Prefab
Per dire all'istanza di seguire completamente il suo prefab padre, e quindi rendere anche la scala Z legata al padre, è possibile usare i tre tasti nel pannello Inspector, subito sotto il nome del gameObject:
Select seleziona il prefab padre nel pannello Project.
Revert fa sì che l'istanza selezionata diventi di nuovo come il prefab padre in tutto e per tutto, perdendo tutte le modifiche locali a qualunque proprietà. Premete Revert e vedrete Cube2
tornare ad essere un cubo, e il campo Z scale nell'Inspector non più in grassetto.
Per scoprire cosa fa Apply, modificate di nuovo la Z in scale a 3. Il cubo Cube2
è di nuovo largo, e la sua scalatura Z di nuovo custom rispetto al prefab a cui è legata.
Premete Apply. Vedrete che le modifiche specifiche di Cube2
vengono riportate sul prefab Cube
, che ora ha scalatura 3, ed a tutte le altre istanze (in questo caso Cube1
). Apply quindi serve a modificare il prefab sulla base di modifiche che prima erano solo di una specifica istanza.
Come accennato prima, questa possibilità di avere un'istanza con solo alcuni parametri specifici e diversi rispetto al prefab è una caratteristica che dà molta libertà d'azione, ma che può confondere.
Si pensi ad un caso in cui in un gioco di simulazione in cui c'è una città con tante macchine rosse, tutte uguali come forma e tutte dello stesso colore, di cui quindi viene creato un prefab. In un secondo momento, serve una macchina di un colore bianco. Si potrebbe modificare solo il colore di una delle auto in una certa scena assegnandogli un materiale.
Di seguito, per motivi di gameplay si potrebbero cambiare le dimensioni delle auto modificando il prefab.
Ancora, si potrebbe cambiare il colore delle auto selezionando un'istanza e cambiando il materiale da rosso a blu, e premendo Apply
. Il prefab verrebbe modificato con il nuovo materiale, ma l'auto bianca rimarrebbe invariata perché per quella specifica istanza il materiale è slegato dal prefab. Il problema nasce se, a seguito di una modifica sull'auto bianca, viene premuto Apply
. Ora tutte le auto sono bianche perché è stato modificato il prefab a monte.