SetActive的反应有所不同

时间:2018-11-28 06:08:09

标签: c# unity3d multidimensional-array gameobject

取决于输入字符串,我想在脚本中激活我的GameObject。我的GameObjects拥有一个公共String,我将其与给定Array的值进行比较:

GameObject parent = GameObject.Find("Pick Ups");
int childCount = parent.transform.childCount;
foreach (var s in arr)
{
  for (int i = 0; i < childCount; ++i)
  {
    // Deactivate Target if it is not part of the Active Objects List
    if (s == parent.transform.GetChild(i).GetComponent<Rotator>().targetID)
    {
      parent.transform.GetChild(i).gameObject.SetActive(true);
      Debug.Log("Element " + s + " activated");
    } else { 
      parent.transform.GetChild(i).gameObject.SetActive(false);
    }
  }
}

这很好。现在,我增加了从输入中获得的信息量,将其存储在3维数组中,并循环抛出了包含与以前相同信息的第一个维:

var tArr = aTLString.Split('~')
                    .Select(x => x.Split('^')
                                  .ToArray()
                                  .Select(y => y.Split('`'))
                                                .ToArray())
                                  .ToArray();

for (int j = 0; j < tArr.GetLength(0); ++j)
{
  for (int i = 0; i < childCount; ++i)
  {
    // Deactivate Target if it is not part of the Active Objects List
    if (tArr[j][0][0] == parent.transform.GetChild(i).GetComponent<Rotator>().targetID)
    {
      parent.transform.GetChild(i).gameObject.SetActive(true);
      Debug.Log("Element " + tArr[j][0][0] + " activated");
    } else { 
      parent.transform.GetChild(i).gameObject.SetActive(false);
    }
  }
}

这一次,元素未激活。我收到控制台反馈,该元素已激活(因此tArr [j] [0] [0]包含正确的字符串),但SetActivate似乎无法正常工作。

我不明白这个问题

1 个答案:

答案 0 :(得分:1)

tArr上的每次迭代中,您正在全部对象上调用SetActive
即使对象在第一遍中匹配,它也会在后续遍中被停用,从而使仅激光遍有效。

您的算法等同于(试图使其尽可能简洁):

public class Thing
{
    public int Id;
    public bool Active = false;
    public Thing(int id) { Id = id; }
}

void Main()
{
    var targetIds = new int[] {2, 5, 7 };
    var things = new Thing[] {new Thing(1), new Thing(2), new Thing(3)};

    foreach (var id in targetIds)
    {
        foreach (var thing in things)
        {
            thing.Active = thing.Id == id;
            Console.WriteLine($"{thing.Id} active: {thing.Active}");
        }
    }
}

这将输出:

1 active: False
2 active: True
3 active: False
1 active: False
2 active: False
3 active: False
1 active: False
2 active: False
3 active: False

您可以看到,即使ID 2在targetIds的第一次迭代中被匹配,它也会在随后的遍历中重置。

您可能想做的是首先将所有对象设置为非活动状态,然后才在tArr上进行迭代并激活匹配的对象,但不要停用不匹配的对象。

或者,如果对象的ID包含在tArr中,则可以仅对对象进行一次迭代并激活它们。

foreach (var thing in things)
{
    thing.Active = targetIds.Contains(thing.Id);
}