No errors and code is firing but it's not working?

I’m trying to assign each game object in a list their own parent and add an LOD group to that parent. When debugging I see that it goes over every child, 1359 children and the loop reaches 1358 as it should, but not all of the children have their own parent. No errors, no warnings, nothing, it just doesn’t work.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class GenerateParentAndLODs : MonoBehaviour
{
    public Transform parent;

    private void Start()
    {
        Debug.Log(parent.childCount); // logs 1359

        for ( int i = 0; i < parent.childCount; i++ )
        {
            Debug.Log(i); // logs 1358

            Transform child = parent.GetChild(i);

            GameObject obj = new GameObject();
            obj.AddComponent<LODGroup>();
            obj.transform.position = Vector3.zero;
            obj.name = "LOD " + i.ToString();

            obj.transform.parent = parent;
            child.transform.parent = obj.transform;
        }
    }

}

The problem with your loop is that you are removing children from the parent, which changes the childrens order.

Think of it this way. When i = 0, you take the child from index 0 and set its parent to the obj. At this point, child in i = 1 now moves into index 0. So when you access i = 1, it’s now actually the child that was in i = 2 position (which has moved as well.)

Think of it like a line at a store. As the person at the front gets told to go in, the next person now is in the front of the line. But you’re skipping them because you’re telling it to go to the second person in line. You also don’t error out because you add more children which covers the ones you remove.

While I don’t suggest this method, you could always access index 0 1359 times. Otherwise, there are other ways of handling this.

1 Like

You could do what @Brathnann suggested, using a while loop:

while (parent.childCount > 0)
{
    var child = parent.GetChild(0);

    // your code... just make sure that you always unparent the current child
    // or else you'll get an infinite loop
}

Or alternatively, you can make two loops, the first one to add all the children in a list, let’s call it “childrenList”, then the second one that loops over the “childrenList” and do the work you need. Think of “childrenList” as a frozen state of the children, that does not get altered when you reparent any child. This will always work, even if you don’t reparent all children.

var childrenList = new List<GameObject>();

for (var i = 0; i < parent.childCount; i++)
    childrenList.Add(parent.GetChild(i));

for (var i = 0; i < childrenList.Count; i++)
{
    Debug.Log(i);

    var child = childrenList[i];

    // your code...
}

I wouldn’t do the while loop since OP is adding children onto the parent as well. I’m guessing this would result in an infinite loop since childCount would always be greater than 0.

The second method would also be good.

1 Like

Yes, I specified that they need to make sure that, ultimately, not child remains under the parent to avoid an infinite loop. Taking a deeper look at the code, you’re right, this line obj.transform.parent = parent adds a new child to the parent.