Incremental Parenting

Hi,
I’m going around in circles attempting to solve a fairly simply problem.
I have an object with several children. I want to find which of those children have children (if any) and then parent another object to the first child without a child.

So for example.

Sphere

TargetObj
-Child1
-Child2
-Child3

So sphere object should parent to the first available child of TargetObj that doesn’t already have a child.
At the moment, I have this:

  void ChildArray()
    {
        Target = new Transform[transform.childCount];  //Array of children
        for (int i = 0; i < transform.childCount; i++)
        {
            Target[i] = transform.GetChild(i);
        }
        foreach (Transform child in Target)
        {
            if (child.transform.childCount == 0)
            {               
                Debug.Log(child);
        newTarget = child;
                Sphere.transform.parent = newTarget;
            }

The above kind of works, the debug.log(child) shows me that Child1, Child2, Child3 all have no children (great!). Unfortunately when I parent the sphere to the ‘child’ the sphere always defaults to the last child object (child3), I assume because it’s the last object in the hierarchy. But I want the sphere to parent to child1, or whichever is the first object that doesn’t already have a child. I’ve gone around in circles trying to make that happen, I feel like I’m missing a step.

Any help appreciated.

Surely you want to break out of the “foreach” when you’ve done the parenting then. You don’t, you just continue iterating Target.

If you’re completely finished at that point, simply return after the parenting.

Also, “child.transform.childCount”. Why are you doing this? The “child” IS a Transform. You’re accessing the Component.Transform which just gets itself. Just do “child.childCount”.

Also, you don’t need to create an array, you can just iterate the children like this:

void ChildArray()
{
    foreach (var child in transform)
    {
        if (child.childCount == 0)
        {         
            Debug.Log(child);

            Sphere.transform.SetParent(child);
            return; // or "break" if you have more work to do in this method.
        }
    }
}
1 Like

Thanks MelvMay for your help.

The codesnippet wasn’t complete, I just posted the relevant parts, it will be used from OnTrigger, and part of my StateMachine, I was just testing a simple script, where by I spent most of the day looking at various techniques for finding children and grandchildren… I had several other methods that ‘kind of worked’.

I seem to get stupider the more I look at simple code, usually if I let it go for a few days, and work on other stuff, coming back with fresh eyes, I notice my stupidity more clearly. :slight_smile: But I’m a novice with C#, and only now starting to learn more intermediate techniques. (So be gentle…:))

This did confuse me many times, I had tried both options in the hope I was getting closer to the desired outcome, but did recognise that as an issue. Looking this morning at previous attempts I did change from child.childCount, to child.transform.childCount, But I’m not sure I know why I did… :wink:

But thank you for the entire post and criticisms, I will now look exactly at each line, and try and fully understand each bit of the code to improve.

I do have some questions, your codesnippet gave two errors:

Error CS1061: ‘object’ does not contain a definition for ‘transform’ and no accessible extension method ‘transform’ accepting a first argument of type ‘object’ could be found (are you missing a using directive or an assembly reference?)']

Error CS1503 Argument 1: cannot convert from ‘object’ to ‘UnityEngine.Transform’

I simply changed “var child in transform” to “Transform child in transform” and that worked fine, but am curious as to why your version didn’t work? “var child” seems to returning an object and not a transform?

The other peculiar thing I noticed, I accidentally tried your code from Update, rather than Start. (It won’t be running in update) but I noticed the sphere object would move around in Update, sometimes being parented to Child1, Child2, Child3, depending on my mouse hovering or clicking in the inspector over the those objects… So if I hover on Child1, the Sphere is moving to Child2, and sometimes to Child3.

Not sure I understand why hovering the mouse is parenting to a different object, obviously in update the code is running continuously, but why is it getting a different result every few seconds?

Shouldn’t it be getting the same Child1 result each time regardless?

Again thanks for your help, very much appreciated.

Just wanted to say thanks again MelvMay…

I have had time today to actually understand a lot more. (Managed to integrate it into my Statemanager).

This bit didn’t compute with me at first, but very obvious now.

I was wrongly under impression that I wanted foreach to iterate over every object, and choose the first object with no child, the break or return part is indeed pivotal to stopping at the first object with no child, and the reason why so many of my attempts left me constantly with the third object. Really stupidly didn’t understand it’s significance.

Anyway, thank you again for taking the time, it’s nice to actually learn the error of my ways and gain some knowledge in the process.

Much appreciated. :slight_smile:

1 Like

No worries, sometimes the most obvious ways to approach it are the least obvious to discover. :wink:

1 Like