Why when i loop over all children of a gameobject i'm getting only one result ?

My goal is to make two methods one will loop and will get all the children objects that are only under Elevator.

The second one will loop and get all the children objects under Elevator and also if there are childs of childs to get them too like the OnTop Detector.

If i have now the method RotateChildren so to make another method like RotateChildren1 that will get all the childs of childs too.

In the Hierarchy i have under Elevator 3 children.
When i make a loop i’m getting only the first one the Platform. But i should get also the Platform1 and the Button.

I used a break point on the line:

if (child.name != "Platform")

And it stop only once on this line the name is Platform but it’s not continue to the Platform1 and to the Button.

using UnityEngine;
using System.Collections;

public class ObjectRotate : MonoBehaviour
{

    public float multiplier = 10f;
    private GameObject go;

    void Start()
    {
        if (GameObject.Find("Elevator") != null)
        {
            go = GameObject.Find("Elevator");
        }
        RotateChildren(go.transform);
    }

    void OnMouseDrag()
    {

        transform.Rotate(Input.GetAxis("Mouse Y") * multiplier, -Input.GetAxis("Mouse X") * multiplier, 0, Space.World);
    }

    private void RotateChildren(Transform transform)
    {
        foreach (Transform child in transform)
        {
            if (child.name != "Platform")
                child.parent = transform;
        }
    }
}

Are you familiar with the concept of recursion? Because that’s the easiest way to achieve what you’re looking to do here, and you already have all the tools you need to use it.

Notice that RotateChildren() takes a single parameter, a Transform. And note that within your foreach loop, you are working with a Transform, the child. If that child itself has children, and since RotateChildren() is a function that is specifically meant to go through a Transform’s children and rotate them, then you can just pass child to RotateChildren().

    private void RotateChildren(Transform transform)
    {
        foreach (Transform child in transform)
        {
            if (child.name != "Platform")
            {
                child.parent = transform;
            }
            RotateChildren(child);
        }
    }

What essentially happens is that when you call RotateChildren(child), the program remembers where it is at during the current execution of RotateChildren(), suspends it, and starts over at the top with a new Transform parameter (which happens to be the current child from the first execution of RotateChildren()). It will go through all of that child’s children and perform the same logic. And it will also call RotateChildren() on each of these grandchildren, in case any of them have great-grandchildren.

After each deeper call to RotateChildren() completes, it returns to the execution of RotateChildren() that started it, and that higher execution resumes where it left off. Eventually, the very first highest-level execution of RotateChildren() completes, and control returns back to the Start() function where the whole process got kicked off.

Warning: This will solve your conceptual problem, but judging from the actual logic that you perform in Rotate(), I don’t think it will actually solve the practical problem that you’re attempting to deal with. If I had to guess, I’d say that you should really only be changing a child Transform’s rotation field, and only the highest-level children in the tree that aren’t “Platform”. So I’d recommend the following code:

    private void RotateChildren(Transform transform)
    {
        foreach (Transform child in transform)
        {
            if (child.name != "Platform")
            {
                child.rotation = transform.rotation;
            }
            else // Only visit deeper children if this child did not have its rotation altered.
            {
                RotateChildren(child);
            }
        }
    }

My main goal is to rotate with the mouse the Elevator but not only the Elevator alone but to rotate with the mouse all the Elevator and the child objects under it and as one unit. Not to rotate only the Elevator and not to rotate only the Platform and not only the Button but to rotate it all together as one unit.

So if i attach the script to the Elevator or of i attach the script to the Platform or Platform1 or Button and then with the mouse i will rotate the Button for example it will rotate the whole Elevator. And if i attach the script to Platform1 and then running the game and with the mouse rotate Platform1 it will rotate them all as one group one unit and not only the Platform1.

Now i’m facing some problems:

  1. On the Elevator(Empty GameObject) i added a Animation component so it will override any rotation. So i can’t rotate the Elevator.

  2. When Platform1 and Button in the Hierarchy if i drag them and put them under Platform as childs they will messed up in the scene the Button and the Platform1 scale will be messed up.

Also i want to make that not matter on what object i will attach the script for example if i attach the script on the button it will find all the childs of Elevator then will parent them under Platform and then when i drag the mouse to rotate it will rotate them all as one unit. The idea is that i will be able to attach the script to any object under Elevator and it will rotate with the mouse the whole Elevator.

Here is a small video clip i recorded showing what i mean by moving them all as one unit and what happen when i put the Platform1 and the Button under Platform as childs.

The Button and the Platform1 should be scaled like they are not parent to Platform but if i want to rotate them all i must parent them to Platform else only Platform will be rotated since the script is attached to Platform.

https://www.youtube.com/watch?v=D8NNRdLw8V0