【问题标题】:Checking if all objects of an array is active at the same time Unity C#检查数组的所有对象是否同时处于活动状态 Unity C#
【发布时间】:2020-05-08 09:15:06
【问题描述】:

我尝试编写一个脚本,如果场景中标记为“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;
            }
        }
    }

此代码只是在 one 灯打开时将 allActive 变量设置为 true。

【问题讨论】:

    标签: c# visual-studio unity3d


    【解决方案1】:

    您需要反转检查:

    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!要么在开始时存储这些引用ONCE,或者如果您在运行时生成更多灯光,则实施事件驱动并将新生成的灯光添加到列表中,然后使用该列表进行检查。

    【讨论】:

      【解决方案2】:

      如果我知道您想知道是否所有对象都处于活动状态: 使用 Linq 完成这项工作

      您必须将 using 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 在每一帧中都非常昂贵......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-28
        • 1970-01-01
        • 2021-05-24
        • 1970-01-01
        • 2020-01-11
        • 2019-12-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多