首先,我需要停用游戏对象,然后在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)
,但一定是错的,因为对象不会复活......
答案 0 :(得分:8)
问题是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);
}
下面是我制作的包装器,即使它们处于非活动状态,也可以按名称,标签或图层查找游戏对象。
你不应该每帧使用这些因为它们很慢。如果在Start
或Awake
函数中使用它们,它们就很好。
找一个GameObject:
<强> USAGE:强>
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<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:
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:
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;
}
查找所有游戏对象(请注意以下所有功能名称中对象中的&#34; s&#34; ):
<强> USAGE:强>
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();
}
通过Tag找到不活跃的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();
}
答案 1 :(得分:2)
在你的情况下,Invoke是一个比协程更好的选择。另外,据我所知你不能找到一个非活动对象,所以你应该将找到的对象分配给一个字段。
var obj;
void BarDeactivate(){
obj = GameObject.Find("OBJ");
obj.SetActive(false);
}
void BarReactivate(){
obj.SetActive(true);
}
通过Invoke这样调用它们:
Invoke("BarDeactivate", sec);
Invoke("BarReactivate", sec);
答案 2 :(得分:-1)
我对ARCore,Vuforia等存在此问题,因为GameObject在被跟踪之前是不活跃的。一种方法是等待目标被识别,然后寻找GameObject,但是,如果它们是手动不活动的,则唯一(不复杂?)的另一种方法是手动列出它们并将它们链接为带有脚本的公共数组。如果您的脚本已链接,那么即使是无效的GameObject也将可以访问。