Imparare UnityPrincipianti

I Prefabs

I prefabs (abbreviazione che sta per ‘prefabbricati‘) sono dei gameObject prefabbricati .
Essi sono dei gameObjects “salvati” all’interno delle cartelle del progetto.
I prefabs mantengono tutte le caratteristiche di un gameObject, scripts, modelli, materiali, valori degli scripts ecc… e si potranno inserire nella scena a nostro piacere, sia da codice che trascinandoli dalla cartella in cui si trovano (nel pannello Project) fin dentro alla Hierarchy o direttamente nel pannello della scena.

A cosa possono serivere i Prefabs?

Mettiamo per esempio di  voler far sparare il giocatore.
Dovremmo “istanziare” l’oggetto “proiettile” che vorremmo far apparire nel punto di fuoco del giocatore.
Istanziare significa “creare una copia dell’originale” all’interno della nostra scena, tramite codice.
Nel momento dello sparo creeremo dunque un’istanza dell’oggetto “proiettile”.
L’oggetto proiettile è il nostro oggetto prefabbricato, un prefab.

Per creare un prefab basta trascinare un qualunque gameObject dalla nostra Hierarchy fin dentro una cartella del progetto (Project).

I prefabs vengono quindi creati (prefabbricati) all’interno di Unity e poi potranno essere istanziati anche più e più volte nel momento del bisogno. Sono essenzialmente dei gameObject che vengono salvati nella cartella del progetto per poi essere riutilizzati in diverse situazioni anche semplicemente trascinandoli nella scena, oppure, come nel caso dei proiettili, tramite codice.

I prefabs sono utili ogni volta che un oggetto deve comparire più di una volta, e deve avere caratteristiche uguali o simili a quella di un altro, ma non per questo sempre identiche. Ogni volta che un prefab viene messo in scena, si dice che quella è un’istanza (una specie di clone) del prefab stesso.

Modificando un prefab padre che abbiamo già all’interno del pannello Project, tali modifiche si ripercuoteranno su ogni istanza nella scena.
In questo modo, se nella scena o in più scene avessimo tanti oggetti che sono istanze di un prefab e volessimo apportare delle modifiche a tutti loro, non dovremmo andare andare a cercare ogni singolo oggetto nelle scene per fare le stesse modifiche su ognuno di essi mabasterà apportare le modifiche al prefab padre nella cartella dove l’abbiamo creato, nel pannello Project.

Ovviamente gli unici parametri che non saranno mai in comune tra le istanze e non verranno ereditati saranno le coordinate del transform perché le istanze saranno sempre posizionate in punti diversi delle scene.

Quando nella scena selezioneremo un gameObject che è un’istanza di un prefab, vedremo che apparirà questo piccolo menu aggiuntivo nell’inspector, con tre tasti.

  • Select seleziona il prefab padre nel pannello Project mostrandoci quindi di quale prefab è quell’istanza.
  • 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à.
  • Apply serve a modificare il prefab base sulla base delle modifiche effettuate a quella specifica istanza.

 

Se per esempio avete un gioco con un determinato tipo di nemico che si dovrà ripetere nella scena o anche in altre scene, potreste creare un prefab di esso ed utilizzare le sue istanze semplicemente trascinandole all’interno delle scene.
Se poi vorrete cambiare solo un particolare di un’istanza, potrete semplicemente farlo modificando il gameObject nella scena.
Quando modificare una caratteristica ad un’istanza nella scena, quella caratteristica verrà posta in grassetto per evidenziare che è stata modificata rispetto al suo valore di base presente sul prefab da cui proviene.
A quel punto però, state attenti a non premere “Apply” perché se lo farete, le modifiche effettuate su quell’istanza saranno applicate anche al prefab padre nella cartella del progetto.

Essendo un prefab un gameObject a tutti gli effetti, essi potranno essere composti da scripts e componenti di ogni genere e potranno avere una loro gerarchia, con childrens e quant’altro si può avere su un normale gameObject.

Cosa succede se si cancella un prefab dalla cartella del Project? Tutte le istanze verranno cancellate?
La risposta è no, non succede nulla di particolare. Le vostre istanze non verranno ne cancellate ne modificate. Semplicemente, appariranno in rosso sulla Hierarchy perché verrà a mancare il collegamento con il prefab.
Ma quel punto le istanze non saranno più collegate tra loro e saranno come dei normali gameObjects nella scena. Sul piccolo menu, al posto dei pulsanti apparirà la scritta in giallo Missing.
Per scollegare completamente un’istanza dal suo prefab, dovrete andare nel menu GameObject e scegliere Break Prefab Instance.

Istanziare un prefab da codice

Proviamo a creare un metodo che istanzi un prefab nel momento in cui il giocatore preme un tasto. Un classico esempio di come emettere un proiettile dal giocatore (o volendo anche da un nemico).

Per creare un’istanza si usa il metodo Instantiate che appartiene ad ogni oggetto ed ha molte variabili a seconda di quali parametri vogliamo impostare nel momento della creazione dell’istanza.

using UnityEngine;

public class Player : MonoBehaviour {

    public GameObject PrefabOriginale;




	void Spara () {
        //Istanzia l'oggetto proiettile, creando una copia del PrefabOriginale
        GameObject proiettile = GameObject.Instantiate(PrefabOriginale);
	}


    void Update()
    {
        // Alla pressione di Fire1, esegui il metodo Spara()
        if (Input.GetButtonDown("Fire1"))
        {
            Spara();
        }




    }



}

In questo modo, ad ogni pressione del tasto Fire1 (che di default è il tasto Ctrl della tastiera) verrà creato un nuovo oggetto, istanza del prefab che abbiamo scelto.

La riga
GameObject.Istantiate(PrefabOriginale);
è però ancora molto vaga. Non abbiamo specificato il punto in cui vorremo che venga creata l’istanza, la sua rotazione e altri parametri che potremmo specificare usando le diverse versioni del metodo Instantiate().

using UnityEngine;

public class Player : MonoBehaviour {

    public GameObject PrefabOriginale;




	void Spara () {
        //Istanzia l'oggetto proiettile, creando una copia del PrefabOriginale impostando la posizione e la rotazione
        GameObject proiettile = GameObject.Instantiate(PrefabOriginale,transform.position,Quaternion.identity);
	}


    void Update()
    {
        // Alla pressione di Fire1, esegui il metodo Spara()
        if (Input.GetButtonDown("Fire1"))
        {
            Spara();
        }




    }



}

 

Ora abbiamo aggiunto sia la posizione che la rotazione iniziale che l’istanza dovrà avere nel momento in cui verrà creata.

GameObject.Instantiate(PrefabOriginale,transform.position,Quaternion.identity);

Con transform.position gli abbiamo detto di creare l’istanza nel punto di posizione dove si trova il trasform su cui è questo script, ovvero sul punto di posizione del Player.
Con Quaternion.identity gli abbiamo detto di mantenere la rotazione di default che possiede il prefab padre del proiettile.

In questo modo avremo i proiettili creati sempre nella posizione del Player. Basterà dunque assegnare al prefab del proiettile uno script che lo faccia muovere in avanti sin dal momento della sua creazione.

Conclusioni finali

Ovviamente questo script è ben lontano dall’essere un sistema completo e funzionale per l’azione di fuoco del giocatore. Dovremmo impostare il punto esatto di fuoco rispetto al player (praticamente il punto sull’arma che spara), la sua direzione, in alcuni casi anche la velocità del proiettile in base alla velocità del giocatore…
In questa lezione abbiamo solo visto una delle tante funzionalità dei prefabs gestiti da codice.
Inoltre, vedremo in seguito che esiste un modo più performante (a livello di performance hardware) di far “sparare” il giocatore o i nemici, perché istanziare e distruggere gli oggetti sono azioni che necessitano di risorse che potrebbero concepire un calo di framerate se effettuate su molti oggetti a run-time, sopratutto necessitano di un uso di memoria che potremmo evitare usando un sistema di Pooling ovvero non distruggendo gli oggetti per poi farli ricreare, ma riutilizzando sempre gli stessi.

5 pensieri su “I Prefabs

  1. Ciao, grazie per il tutorial. Quando clicco sul Prefab il menu che dovrebbe comparire nell’Inspector che tu indichi ha voci differenti ossia “Open”, “Select” e “Overrides” (non “select”, “revert” e “apply”) e in più sono in grigetto quindi non sono selezionabili

    1. Ciao Alessio,
      che versione di Unity usi?
      Dalla versione 2018.3 i prefabs sono leggermente cambiati, con l’avvento dei “Nested Prefabs”, ovvero con i prefabs che possono contenere al loro interno dei prefabs figli.
      Mi ne occuperò di questo aspetto quando questa feature sarà un po’ più stabile e collaudata. Per ora il funziomento di base dei prefabs rimane quasi lo stesso delle precedenti versioni.

Lascia un commento

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