2017-07-28 4 views
0

GameObjectのすべての子を別のものに変更しようとしています。Unity3D:子どもたちを再育てながらループする際の問題

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

このコードは、子を部分的に切り離し、元の親にいくつかの子を残します。上記のコードを使用して上記の操作を実行します。

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

これは完全に機能します。私もparent.GetChild(i)と一緒に使用し、同様の問題が発生します。どこに行方不明ですか?

+0

することはありますパターンが省略されているオブジェクトに? – Serlite

+0

子供の "リスト"から項目を取り除いて親を変更すると、基本的に子供が削除されているようです。 「子」が削除され、リストがシフトすると、次の「子」はキュー内でそのターンを逃す。 2番目のループでは、各子は 'collect'の子ではなく(最初のループのように)、' collect'の配列全体をループして親を変更することができます。アレイ。 – ryeMoss

答えて

2

コメントで説明したように、子供たちのコレクションを「foreach」を使って繰り返しているのと同時に変更しているので、アイテムが欠落しています。一般的にはこれは悪い考えです。あなたが行っている作業を正確に把握していない限り、コレクションを繰り返している間はコレクションを変更しないでください。

あなたが見つけた1つの解決策は、コレクションのコピーを作成し、コピーを繰り返し、元のコレクションからアイテムを安全に削除することです。オブジェクトにタグを付けてからFindGameObjectsWithTagを呼び出すと、すべてのGameObjectを1つずつ検索するだけでなく、エラーが発生する可能性があるため、不必要に非効率的です(タグを削除するのを忘れた場合、奇妙な動作が発生します)。あなたがリストを作る方がいいでしょう:

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

簡単、まだこのような場合には限り親が子を持っているとして、最後の子を削除するには、whileループを使用することです:

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

ありがとうございます。私が最初の子供の親を変えたとき、2番目の子供が最初になり、2番目の子供(実際には3番目の子供)に行き、その結果、部分的な操作になりました! したがって、子どもたちはGetChild(childcount-1)から子どもにアクセスします。 –

関連する問題