- Home /
How do I retrieve deep levels of nested child transforms with a generic snippet of code
This current project exists in Unity 2018.2.2f1.
I want to loop through the children of children of children of a root parent to execute a method of the object/transform at the 4th level of a parent/child ladder.
I have gone about this for two days now. Most answers are posted for gameobjects which the children are not. They are transforms. So for anybody reading this get this point straight before any comments or posts. I understand the concept, at least this is what is drilled in by those dealing with multi levels of children. I can not seem to get to 4th level of children. I suspect my Transform designations are a mess, but I cant seem to find a straight forward generic code snippet for this. I believe I am mixing gameobjects with transforms with arrays. If my code is terribly wrong then so be it. It is a mishmash of multiple posts of attempts. I have done due diligence in many , many runs of code to no avail. If my grammar incorrect excuse you and show me and the future readers kindness and mercy. Please no techno babble, condensending remarks or toss in comments. Only revelance here. This answer is not just for me but for future readers who might not be well versed in Unity or C, GameObject manipulations. The last item mentioned is the wall that all new developers come up against when their game size exceeds their forte(surprise). I am asking for an expert touch so that in the future any body coming along will be able to run through your solution and add any nest hierarchy and display a stream of debug.log line of any parent child nesting/depth. This is missing from all the posts I have seen. I have consigned myself to stick with strictly Transforms but am open to gameobject usage as well. I just want to stop wasting time going round and round reading 2 level parent/child answers. The Rgo gameobject is where it starts and I have access to the methods and properties. Lets go deeper. I am really trying to execute a script method in 4th level gameobject (TSPos and TSNeg).
Attached is a unity run screen that shows the hierarchy without me exposing any data as expressed in my Non-Disclosure Agreement with my contracting lead. As can be seen there is a child(tsChild) of a child(child) at the lower end of the relation that display the same name. tsChild is supposed to be a child of 'child' but I get the same item.
I am not trying get scolded by authoritarians if this post deems unacceptable. Supply a solution that we can all use and dispel with the ruler across the knuckles diatribe for the sake of the sanctity of the community. I have read the docos and posts ad infinitum. I have also run up against attempts in Unity that have gotten the final statement 'Sorry for the inconvenience' or 'We missed that one' or 'this method has been deprecated' only to have it resurface in a future update.
Thank you all. I hope I have supplied enough information about what I have come up against and what the community need is here.
Now I can go take a mandatory shower and eat correctly before I smell like food to my dogs.
hello, you didnt attach any code, or i cant see it. second you want to retrieve all the childs of the object? and the childs of the childs of the childs? all in just one array? or i am missing something? whats your exact need? you need to save it by its level of parent? or all in one list/array?
Answer by Ymrasu · Feb 05, 2019 at 10:25 PM
This is done through GetChild method of transform. Transforms act as arrays that hold child transforms. The index of the children are their placements within the Hierarchy.
// We can use a 'current' transform to help transverse
Transform current = transform; // current transform is Ring Gen
Debug.Log(current.name);
current = current.GetChild(0); // current transform is now RingPair (0)
Debug.Log(current.name);
current = current.GetChild(0); // current transform is now TSPair (0)
Debug.Log(current.name);
current = current.GetChild(0); // current transform is now TSPos
Debug.Log(current.name);
// OR we can chain the getchild calls
// transform is parent or level 1, then chain 3 getchild to get to level 4
current = transform.GetChild(0).GetChild(0).GetChild(1); // last GetChild use index 1 for the second child (TSNeg)
Debug.Log(current.name);
Or if you just want to loop through all the children you can set up a foreach loop:
void Start()
{
DisplayChildren(transform);
}
void DisplayChildren(Transform trans)
{
foreach(Transform child in trans) {
Debug.Log(child.name);
if (child.childCount > 0) {
DisplayChildren(child);
}
}
}
this loops through the children of the provided transform, then if that transform has children it calls itself to loop through those children as so forth.
hello, your code will not work altought i think is closer to what he is searching, you need to change the foreach for a classic for loop :)
int childCount = parent.childCount;
for(int iterator = 0; iterator < childCount; iterator++)
{
DisplayChildren(trans.GetChild(iterator));
}
foreach loops work on transforms to get the children of the transform
@Ymrasu Yes Neg and Pos during runtime from an instantiated gameobject later. I am writing down the firing sequence of the whole instantiation event. $$anonymous$$ight the problem lie in the script execution sequence? Are run time instantiated from runtime instantiated left till last in the execution sequence? Will profiler show this?
The initial pairs are instantiated from a script on parent prefab which is instantiated by the ring. I believe this thread could be closed at this time as I have the recursive routine that produces very clear results. The instantiated tsPairs are built from a single prefab. The underlying children are instantiated from a GO that is transform and a script component. The script component uses the tsPairs prefab. I now have to get the hierarchy level that I want selected so execute the method.
@Ymrasu & @xxmariofer Problem solved!
Thank you to both of you for getting me passed this point.
Your efforts pointed out something. I had the NegPos instantiations in the the start().
I had to move those to a separate method in the script and call that after the main prefab instantiation. When there is a prefab of prefabs the start() code always executes in a non compliant order. If there is a way to control this I would like to know. Else you call the method right after instantiation and you control the order. Had I seen this escapee before I would not have had to post this question.
But now we are all the smarter. @xxmariofer : I tried the for loop and eventually settled on what @Ymrasu supplied. I also used the secondary Transform selection that @Ymrasu supplied to copy the transform to the method parameter.
Now the recursiveness creates a completely generic routine no matter how large a Prefab is. @Ymrasu If you post the answer I will accept. Thanks again.
And may the future Unitarians see this and have it solve their request.
Here is the code I added:
Transform current = transform; // current transform is Ring Gen
DisplayChildren(current);// Recursive and grabs everything.
Answer by thinkblue · Jan 15 at 09:25 PM
// global class variable
Transform childFound = null;
Transform CustomFindChild(string key, Transform parent)
{
foreach (Transform child in parent)
{
if (child.name == key)
{
childFound = child;
} else
{
if (child.childCount > 0)
{
if (childFound == null)
{
CustomFindChild(key, child);
}
}
}
}
return childFound;
}