首页 > 解决方案 > 检查数组的所有对象是否同时处于活动状态 Unity C#

问题描述

我尝试编写一个脚本,如果场景中标记为“Light”的所有灯光同时处于活动状态,则游戏会继续进行。到目前为止,我找到的答案都没有帮助。我总是最终只扫描活动对象,只是随机跳出循环,或者在找到一个活动对象时停止。这是一段简单的代码,根据其他帖子应该可以工作

    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-studiounity3d

解决方案


您需要反转检查:

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

或者您可以使用Linq在一行中执行此操作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每一帧!要么在开始时将这些引用存储一次,要么在运行时生成更多灯光,实现它的事件驱动并将新生成的灯光添加到列表中,然后使用该列表进行检查。


推荐阅读