清除列表并重新添加对象会导致对象数量相同?

时间:2018-11-30 19:23:23

标签: c# unity3d

我有一个List存储了所有child gameobjects

List<GameObject> goChildren = new List<GameObject>();

在Start()函数中,我有这个:

foreach (Transform child in transform)
{
    goChildren.Add(child.gameObject);
}

添加所有子项。

然后我有一个“ Hit()”方法,当玩家击中一个子对象时会调用该方法。

然后子对象应被销毁,列表应被清除,所有剩余的对象应重新添加。

这是我尝试处理的方式:

Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, actionRange))
{
    Destroy(hit.transform.gameObject);
}

goChildren.Clear();
foreach (Transform child in transform)
{
    goChildren.Add(child.gameObject);
}

但是我的List goChildren中存储的对象数量与以前相同。

我用Debug.Log(goChildren.Count)显示了Hit()方法之前和之后的子代数。

两个都告诉我清单上有566个孩子。

  

我认为这段代码应该做的是:

     
      
  1. 消灭一个孩子
  2.   
  3. 清除列表
  4.   
  5. 将剩余的孩子添加到列表中
  6.   

2 个答案:

答案 0 :(得分:1)

尝试一下:

fh = open("./test.txt")
lines = fh.readlines()
for i in range(len(lines) - 2):
    print(lines[i])
    print(lines[i + 2])

答案 1 :(得分:1)

您可以阅读here,对象破坏发生在当前更新循环之后。因此,当您重新填充列表时,实际上该对象仍然存在(并且转换列表项已对其进行引用)。 因此,更好的解决方案是通过

从列表中删除元素引用
goChildren.Remove(***obj reference***)

goChildren.RemoveAt(***obj index***)

,然后销毁游戏对象。 此外,没有必要删除和读取未修改的更改,它无缘无故地在幕后产生了许多不必要的数组修改。 (Remove和RemoveAt函数还会在被删除的元素之后复制移位的部分,如果被删除的元素位于大列表的开头,这可能是一项巨大的工作。)

请注意,为新列表添加大量元素是次优的,因为列表后面的数组是重新分配并重复复制的。 列表的默认容量为4,当大小超过列表容量时,它将分配一个大小为8的新数组,然后复制内容。 16、32、64等也会发生同样的情况,因此,当您填充从0到566个元素的列表时,

  1. 分配4
  2. 分配8,复制
  3. 分配16,复制
  4. 32,复制
  5. 64,复制
  6. 128,复制
  7. 256,复制
  8. 512,复制
  9. 1024,复制

Source

您可以通过

预分配列表
List<GameObject> goChildren = new List<GameObject>(capacity);

但这只是初始性能提升,请尝试使用

HashSet<T>

如果元素的顺序不重要。您所需要的只是一个良好的哈希函数,在大多数情况下都可以轻松实现。