按名称、标签或图层查找非活动游戏对象



首先,我需要停用一个游戏对象,然后在 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)但一定是错的,因为物体不会复活......

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

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

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

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

您不应该每帧都使用这些,因为它们很慢。如果用于StartAwake功能,它们会很好。

找到一个游戏对象:

用法:

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

按名称查找处于活动状态的游戏对象:

GameObject FindInActiveObjectByName(string name)
{
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() 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 FindInActiveObjectByTag(string tag)
{
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() 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 FindInActiveObjectByLayer(int layer)
{
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() 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;
}


查找所有游戏对象(请注意以下所有函数名称中对象中的"s">):

用法:

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

按名称查找处于活动状态的游戏对象:

GameObject[] FindInActiveObjectsByName(string name)
{
List<GameObject> validTransforms = new List<GameObject>();
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() 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[] FindInActiveObjectsByTag(string tag)
{
List<GameObject> validTransforms = new List<GameObject>();
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() 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();
}

按层查找处于活动状态的游戏对象:

GameObject[] FindInActiveObjectsByLayer(int layer)
{
List<GameObject> validTransforms = new List<GameObject>();
Transform[] objs = Resources.FindObjectsOfTypeAll<Transform>() 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();
}

在您的情况下,调用是比协程更好的选择。另外,据我所知你不能.查找非活动对象,因此应将找到的对象分配给字段。

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

通过调用调用它们,如下所示:

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

我在ARCore,Vuforia等方面遇到了这个问题,因为游戏对象在可以跟踪之前是不活动的。一种方法是等待目标被识别,然后查找游戏对象,但如果它们手动处于非活动状态,则唯一的另一种(不复杂?)方法是手动列出它们并将它们作为公共数组与脚本链接。如果您的脚本已链接,那么即使是非活动游戏对象也可以访问。

您可以通过代码找到停用gameobject,并在运行时在检查器中分配:

1-在您必须获取的游戏对象上附加脚本。e.g i have attach " PoliceCarController ";

2 -编写代码

void Start()
{ 
GameObject PoliceCar = GameObject.FindObjectOfType<PoliceCarController>(true).gameObject;
}

最新更新