[英]Find inactive GameObject by name, tag or layer
首先,我需要停用一个游戏对象,然后在 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。 您应该找到 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);
}
下面是我制作的一个包装器,它通过名称、标签或层来查找游戏对象,即使它们处于非活动状态。
你不应该在每一帧都使用这些,因为它们很慢。 如果在Start
或Awake
功能中使用它们是很好的。
找到一个游戏对象:
用法:
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[s]:
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[s]:
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[s]:
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();
}
在您的情况下, 调用是比协程更好的选择。 此外,据我所知,您不能 .Find 一个非活动对象,因此您应该将找到的对象分配给一个字段。
var obj;
void BarDeactivate(){
obj = GameObject.Find("OBJ");
obj.SetActive(false);
}
void BarReactivate(){
obj.SetActive(true);
}
通过 Invoke 调用它们,如下所示:
Invoke("BarDeactivate", sec);
Invoke("BarReactivate", sec);
我在 ARCore、Vuforia 等方面遇到了这个问题,因为游戏对象在被跟踪之前是不存在的。 一种方法是等待目标被识别,然后寻找游戏对象,但如果它们手动不活动,唯一的另一种(简单?)方法是手动列出它们并将它们作为公共数组与脚本链接。 如果您的脚本已链接,那么即使是非活动的游戏对象也可以访问。
您可以通过代码找到gameobject
并在运行时在检查器中分配:
1-在你必须得到的游戏对象上附加脚本。 eg i have attach " PoliceCarController ";
2 -编写代码
void Start()
{
GameObject PoliceCar = GameObject.FindObjectOfType<PoliceCarController>(true).gameObject;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.