按名称,标签或图层查找非活动的GameObject

首先,我需要停用游戏对象,然后在10秒后激活它,所以我认为协同程序是合适的:

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); } 

显然,我不能再使用GameObject.Find所以我使用transform.Find来查找不活动的游戏对象,但当然.SetActive现在不起作用,因为obj实际上不是游戏对象……

如何转换找到的变换,以便可以再次设置它?

我试过obj.gameObject.SetActive(true)但它一定是错的,因为对象不会obj.gameObject.SetActive(true) ……

问题是Unity无法找到不活动的GameObjects。 GameObject.Find只会找到活动的GameObject。 您应该在全局变量中查找并存储GameObject,或者将变量设为public,然后从编辑器中分配它。

我的解决方案使用全局变量然后将GameObject存储在初学者中,这样您就不必再次查找它。

 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); } 

下面是我制作的包装器,即使它们处于非活动状态,也可以按名称,标签或图层查找游戏对象。

你不应该每帧使用这些因为它们很慢。 如果在StartAwakefunction中使用它们,它们就很好。

找一个GameObject:

用法:

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

按名称查找不活动的GameObject:

 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; } 

按标签查找不活动的GameObject:

 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; } 

按层查找不活动的GameObject:

 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; } 


找到所有GameObjects (注意下面所有函数名称中Object中的“s” ):

用法:

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

按名称查找不活动的GameObject [s]:

 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(); } 

通过标签查找不活跃的GameObject [s]:

 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(); } 

通过Layer查找不活动的GameObject [s]:

 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(); } 

在你的情况下, Invoke是一个比协程更好的选择。 另外,据我所知你不能找到一个非活动对象,所以你应该将找到的对象分配给一个字段。

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

像这样通过Invoke调用它们:

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