Questa è un’esigenza che capita almeno una volta in ogni progetto.
Vedremo due metodi diversi per fare una ricerca che “scansioni” anche oggetti non attivi in Hierarchy.
Metodo 1
Come sappiamo, quando abbiamo la necessità di trovare uno specifico gameObject nella scena possiamo andare a cercarlo tramite diversi metodi:
Facendo una ricerca tramite il nome del gameObject :
mygameObject=GameObject.Find(“nomeOggetto”);
oppure facendo una ricerca tramite un tag:
mygameObject=GameObject.FindObjectsWithTag(“tagOggetto”);
oppure ricercando uno specifico script che sappiamo è attaccato su di esso:
mygameObject= FindObjectOfType<myScript>().gameObject;
Tutti queste tecniche hanno però un handicap, ovvero non riescono a trovare un oggetto se non è attivo nella gerarchia.
Vi accorgerete presto che questo è un limite molto fastidioso che vi potrebbe generare diversi grattacapi per diverse ragioni.
Per ovviare a questo problema ci viene in aiuto una funzione che ci permette di fare ricerche anche su oggetti non attivi:
GetComponentInChildren<myScript>();
Questa funzione va alla ricerca di uno script nei childrens di un gameObject e permette di impostare anche la ricerca sugli oggetti inattivi, specificandolo come parametro:
GetComponentInChildren<myScript>(true);
E’ ovvio che il nostro gameObject dovrà trovarsi necessariamente sotto ad un altro gameObject e che la ricerca deve essere effettuata specificatamente su di esso:
myParentGameObject.GetComponentInChildren<myScript>(true);
In questo modo potremmo andare alla ricerca di uno specifico gameObject, anche se inattivo, a patto che si trovi sotto myParentGameObject e che contenga lo script myScript.
Se volessimo ricercare un determinato oggetto senza sapere sotto a quale gameObject si trovi dovremmo fare una ricerca su tutti gli oggetti:
foreach (GameObject allObjects in FindObjectsOfType<GameObject>()){ if(allObjects.GetComponentInChildren<myScript>(true)){ mygameObject=allObjects; return; } }
In questo modo avremo ricercato su tutti gli oggetti attivi con FindObjectsOfType() e se uno di essi contenesse un gameObject (anche se inattivo) che possiede lo script myScript e lo avremo “salvato” su myObject.
Appena si trova l’oggetto in questione, con return; usciamo dalla ricerca.
Metodo 2
Il secondo metodo è molto meno limitativo e ci permette di trovare un gameObject tramite il suo nome (che sia attivo o inattivo) senza la necessità che esso possegga un particolare script.
Questo metodo trova anche i gameObjects nei prefabs.
static GameObject FindByName(string goName) { GameObject go = null; foreach (GameObject obj in Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[]) { if (obj.name.Equals(goName)) { go = obj; return go; } } return null; }
La ricerca che prevede “la scansione” tutti i gameObject di una scena è ovviamente molto dispendiosa in termini di prestazioni ed è altamente sconsigliato eseguirlo in Update().