检查一个数组的所有对象是否同时处于活动状态 Unity C#

问题描述 投票:1回答:2

我试着做了一个脚本,如果我的场景中所有标记为 "光 "的灯同时激活,游戏就会继续进行。到目前为止,我找到的所有答案都没有用。我最后总是发现它只扫描活动的对象,只是随机地跳出循环,或者当它找到一个活动的对象时就停止。下面是一段简单的代码,根据其他帖子,它应该是有效的。

    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。一个 灯光被打开。

c# visual-studio unity3d
2个回答
3
投票

你需要反转检查。

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 每一帧! 要么存储这些引用 一次 或者如果你在运行时产生了更多的灯,则实现事件驱动,将新产生的灯添加到一个列表中,然后使用该列表进行检查。


3
投票

如果我明白你想知道是否所有对象都是活动的:使用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在每一帧中都是非常昂贵的... ...

© www.soinside.com 2019 - 2024. All rights reserved.