简体   繁体   English

Unity3D:在重定孩子时遍历孩子的问题

[英]Unity3D: Issue in looping through the children while reparenting them

I'm trying to change all the children of a GameObject to another. 我试图将一个GameObject的所有子代更改为另一个。

foreach (Transform child in transform) {
child.parent = new_parent.transform;
}

This code detaches the children partially and leaves a few children back in the original parent. 此代码部分分离了子项,并将几个子项保留在原始父项中。 I use the below code to perform the above operation. 我使用以下代码执行上述操作。

foreach (Transform child in transform) {
    child.tag = "collected";
}

GameObject[] collected = GameObject.FindGameObjectsWithTag ("collected");
foreach (Transform child in collected.transform) {
    child.transform.parent = new_parent.transform;
}

And this works perfectly. 这完美地工作。 I also used for along with parent.GetChild(i) and similar issue happens. 我还与parent.GetChild(i)一起使用,发生了类似的问题。 Where am I missing? 我在哪里想念?

As explained in the comments, items are going missing because you're modifying the collection of children at the same time as you're iterating through it with 'foreach.' 正如评论中所解释的,项目丢失了,因为您在使用“ foreach”进行迭代的同时修改了子级集合。 In general this is a bad idea and you should never modify a collection as you're iterating through it (unless you know exactly what you're doing). 总的来说,这是一个坏主意,在遍历集合时,切勿修改集合(除非您确切地知道自己在做什么)。

One solution, which you've found, is to make a copy of the collection, iterate through the copy, and then safely remove items from the original collection. 您找到的一种解决方案是制作该集合的副本,遍历该副本,然后安全地从原始集合中删除项目。 Tagging the objects and then calling FindGameObjectsWithTag is unnecessarily inefficient because it searches through every single GameObject, and also error-prone (if you forget to remove the tags you will get weird behaviour). 标记对象然后调用FindGameObjectsWithTag效率低下,因为它会在每个FindGameObjectsWithTag中进行搜索,并且容易出错(如果您忘记删除标签,则会产生奇怪的行为)。 You're better off making a list: 您最好列出一个清单:

var collected = new List<Transform>();
foreach (var child in transform) {
    collected.Add(child);
}
foreach (Transform child in collected) {
    child.transform.parent = new_parent.transform;
}

Easier still in this case is to use a while loop to remove the last child as long as the parent has any children: 在这种情况下,更简单的方法是使用while循环删除最后一个孩子,只要其父母有任何孩子:

while (transform.childCount > 0) {
    transform.GetChild(transform.childCount - 1).parent = new_parent.transform;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM