- Home /
Recursing through a bone hierarchy: Stack Overflow
My code is at the bottom of the post. The second function, FindChildByName is most important.
It takes a transform (a root bone of a skeleton) and a target name to search for. The idea is that it recurses through the hierarchy until it finds a bone with a matching name, or returns null.
As soon as i run it (without the print statement), unity freezes for approximately two seconds and then halts the script with a StackOverflowException
If i try to stick a debug message in there as shown below, it just freezes indefinitely, because print is very slow and its getting stuck in an infinite loop.
So i'm struggling to debug it. Where am i going wrong?
void ProcessMeldPair(GameObject root, SkinnedMeshRenderer sub)
{
//creating a new object? i guess we're cloning the sub
GameObject newObj = new GameObject(sub.gameObject.name);
newObj.transform.parent = root.transform;
//Cloning renderer
SkinnedMeshRenderer newRenderer = newObj.AddComponent<SkinnedMeshRenderer>();
//Assemble bone structure?
Transform[] subBones = new Transform[sub.bones.Length];
int i;
for (i = 0; i < sub.bones.Length;i++)
{
subBones[i] = FindChildByName( sub.bones[ i ].name, root.transform );
}
//Assemble Renderer
newRenderer.bones = subBones;
newRenderer.sharedMesh = sub.sharedMesh;
newRenderer.sharedMaterials = sub.sharedMaterials;
}
private Transform FindChildByName( string targetName, Transform bone )
{
print("Finding bone: " + targetName);
Transform returnVar = null;
if (bone.name == targetName)
{
return bone;
}
foreach (Transform child in bone)
{
returnVar = FindChildByName(targetName, bone);
if (returnVar)
{
return returnVar;
}
}
return null;
}
Answer by maccabbe · Mar 29, 2015 at 05:28 PM
Line 35 should be
returnVar = FindChildByName(targetName, child);
instead of
returnVar = FindChildByName(targetName, bone);
Are you sure? As far as i can tell, doing that will just repeatedly check the root bone of the hierarchy and go no deeper. Then there's no change from one iteration of the loop to the next.
i'm sure this won't crash, but i don't see how it will accomplish anything either.
Line 35 is currently
returnVar = FindChildByName(targetName, bone);
Which means FindChildByName(targetName, bone) calls FindChildByName(targetName, bone) which then calls FindChildByName(targetName, bone) ad infinitum. Since the function keeps calling itself, more and more memory is being used until the memory stack overflows with information.
If you replace line 35 with
returnVar = FindChildByName(targetName, child);
The new code will not repeatedly check the root bone but ins$$anonymous$$d check the children and therefore go as deep as it can until it returns.
ooooohhh i got mixed up. normally epople would post "you should replace X with Y", so i have a habit of assu$$anonymous$$g the second option is your recommendation, and of not reading properly