我试着做了一个脚本,如果我的场景中所有标记为 "光 "的灯同时激活,游戏就会继续进行。到目前为止,我找到的所有答案都没有用。我最后总是发现它只扫描活动的对象,只是随机地跳出循环,或者当它找到一个活动的对象时就停止。下面是一段简单的代码,根据其他帖子,它应该是有效的。
void Update()
{
bool allActive = false;
GameObject[] allLights = GameObject.FindGameObjectsWithTag("Light");
if(currenObjective > 0 && currenObjective < 3)
{
for (int i = 0; i < allLights.Length; i++)
{
if (allLights[i].activeInHierarchy)
{
allActive = true;
break;
}
}
if (allActive)
{
currentObjective = 2;
}
}
}
这段代码只是在此刻将allActive变量设置为true。一个 灯光被打开。
你需要反转检查。
private void Update()
{
// Since Find is always a bit expensive I would do the cheapest check first
if(currenObjective > 0 && currenObjective < 3)
{
var allLights = GameObject.FindGameObjectsWithTag("Light");
var allActive = true;
for (int i = 0; i < allLights.Length; i++)
{
if (!allLights[i].activeInHierarchy)
{
allActive = false;
break;
}
}
if (allActive)
{
currentObjective = 2;
}
}
}
或者你可以用以下方法在一行中完成 线路 All
using System.Linq;
...
private void Update()
{
// Since Find is always a bit expensive I would do the cheapest check first
if(currenObjective > 0 && currenObjective < 3)
{
var allLights = GameObject.FindGameObjectsWithTag("Light");
if (allLights.All(light => light.activeInHierarchy))
{
currentObjective = 2;
}
}
}
一般性注意:你应该避免使用 FindGameObjectsWithTag
每一帧! 要么存储这些引用 一次 或者如果你在运行时产生了更多的灯,则实现事件驱动,将新产生的灯添加到一个列表中,然后使用该列表进行检查。
如果我明白你想知道是否所有对象都是活动的:使用Linq就可以了。
你必须在你的脚本中添加使用system.Linq。
GameObject[] allLights = GameObject.FindGameObjectsWithTag("Light");
bool result = allLights.All(p => p.activeInHierarchy);
你可以像这样简化你的代码。
private void Update()
{
if(currenObjective > 0 && currenObjective < 3 && GameObject.FindGameObjectsWithTag("Light").All(p => p.activeInHierarchy))
{
currentObjective = 2;
}
}
就像derHugo说的,FindGameObjectsWithTag在每一帧中都是非常昂贵的... ...