Archivio ScriptsImparare C#Tips

Trovare GameObjects non attivi

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().

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.