Trova GameObject non attivo per nome, tag o livello

Innanzitutto, ho bisogno di distriggersre un object di gioco e dopo 10 secondi, triggersrlo, quindi ho pensato che le coroutine fossero adatte:

IEnumerator BarDeactivate(float sec) { yield return new WaitForSeconds(sec); var obj = GameObject.Find("OBJ"); obj.SetActive(false); } IEnumerator BarReactivate(float sec) { yield return new WaitForSeconds(sec); var obj = transform.Find("OBJ"); obj.SetActive(true); } 

Ovviamente, non posso più usare GameObject.Find quindi uso transform.Find per trovare l’object del gioco inattivo , ma ovviamente .SetActive ora non funziona, dal momento che obj non è in realtà un object di gioco …

Come faccio a trasmettere la trasformazione trovata, in modo che possa essere nuovamente triggersta?

Ho provato obj.gameObject.SetActive(true) ma deve essere sbagliato, perché l’object non sarebbe tornato in vita …

Il problema è che Unity non riesce a trovare GameObjects inattivi. GameObject.Find troverà solo GameObject attivo. Dovresti trovare e memorizzare GameObject in una variabile globale o rendere pubblica la variabile, quindi assegnarla dall’editor.

La mia soluzione utilizza una variabile globale quindi memorizza il GameObject nel principiante in modo da non doverlo cercare di nuovo.

 GameObject obj; void Start() { obj = GameObject.Find("OBJ"); } IEnumerator BarDeactivate(float sec) { yield return new WaitForSeconds(sec); obj.SetActive(false); } IEnumerator BarReactivate(float sec) { yield return new WaitForSeconds(sec); obj.SetActive(true); } 

Di seguito è riportato un wrapper che trova oggetti GameObjects per nome, tag o livello anche se sono inattivi.

Non dovresti usare questi frame perché sono lenti. Sono buoni se usati nella funzione Start o Awake .

Trova un object GameObject:

USO:

 void Start() { GameObject objByName = FindInActiveObjectByName("Cube"); GameObject objByTag = FindInActiveObjectByTag("CubeTag"); GameObject objByLayer = FindInActiveObjectByLayer(LayerMask.NameToLayer("CubeLayer")); } 

Trova GameObject attivo per nome:

 GameObject FindInActiveObjectByName(string name) { Transform[] objs = Resources.FindObjectsOfTypeAll() as Transform[]; for (int i = 0; i < objs.Length; i++) { if (objs[i].hideFlags == HideFlags.None) { if (objs[i].name == name) { return objs[i].gameObject; } } } return null; } 

Trova GameObject attivo per tag:

 GameObject FindInActiveObjectByTag(string tag) { Transform[] objs = Resources.FindObjectsOfTypeAll() as Transform[]; for (int i = 0; i < objs.Length; i++) { if (objs[i].hideFlags == HideFlags.None) { if (objs[i].CompareTag(tag)) { return objs[i].gameObject; } } } return null; } 

Trova GameObject attivo per strato:

 GameObject FindInActiveObjectByLayer(int layer) { Transform[] objs = Resources.FindObjectsOfTypeAll() as Transform[]; for (int i = 0; i < objs.Length; i++) { if (objs[i].hideFlags == HideFlags.None) { if (objs[i].gameObject.layer == layer) { return objs[i].gameObject; } } } return null; } 


Trova tutti i GameObjects (nota la "s" nell'object da tutti i nomi delle funzioni di seguito):

USO:

 void Start() { GameObject[] objByNames = FindInActiveObjectsByName("Cube"); GameObject[] objByTags = FindInActiveObjectsByTag("CubeTag"); GameObject[] objByLayers = FindInActiveObjectsByLayer(LayerMask.NameToLayer("CubeLayer")); } 

Trova GameObject inattivo per nome:

 GameObject[] FindInActiveObjectsByName(string name) { List validTransforms = new List(); Transform[] objs = Resources.FindObjectsOfTypeAll() as Transform[]; for (int i = 0; i < objs.Length; i++) { if (objs[i].hideFlags == HideFlags.None) { if (objs[i].gameObject.name == name) { validTransforms.Add(objs[i].gameObject); } } } return validTransforms.ToArray(); } 

Trova GameObject inattivo per tag:

 GameObject[] FindInActiveObjectsByTag(string tag) { List validTransforms = new List(); Transform[] objs = Resources.FindObjectsOfTypeAll() as Transform[]; for (int i = 0; i < objs.Length; i++) { if (objs[i].hideFlags == HideFlags.None) { if (objs[i].gameObject.CompareTag(tag)) { validTransforms.Add(objs[i].gameObject); } } } return validTransforms.ToArray(); } 

Trova GameObject inattivo di Layer:

 GameObject[] FindInActiveObjectsByLayer(int layer) { List validTransforms = new List(); Transform[] objs = Resources.FindObjectsOfTypeAll() as Transform[]; for (int i = 0; i < objs.Length; i++) { if (objs[i].hideFlags == HideFlags.None) { if (objs[i].gameObject.layer == layer) { validTransforms.Add(objs[i].gameObject); } } } return validTransforms.ToArray(); } 

Nel tuo caso Invoke è un’opzione migliore rispetto a una coroutine. Inoltre, per quanto ne so, non è ansible trovare un object inattivo, quindi è necessario assegnare l’object trovato a un campo.

 var obj; void BarDeactivate(){ obj = GameObject.Find("OBJ"); obj.SetActive(false); } void BarReactivate(){ obj.SetActive(true); } 

Chiamali tramite Invoke in questo modo:

 Invoke("BarDeactivate", sec); Invoke("BarReactivate", sec);