Ragdoll

Is the idea of the MatchAllChildTransforms method in UnitRagdoll more to teach recursion? Personally I would use the built in Unity method GetComponentsInChildren and also SetPositionAndRotation (just found that one).

So I would end up with something like:

private void MatchAllChildTransforms(Transform original, Transform ragdoll)
{
    Transform[] childTransforms = GetComponentsInChildren<Transform>();
    foreach (Transform childTransform in childTransforms)
    {
        Transform cloneChild = ragdoll.Find(childTransform.name); //finds original transform
        if (cloneChild == null) continue;
        childTransform.SetPositionAndRotation(childTransform.position, childTransform.rotation);
    }
}

Rather than:

private void MatchAllChildTransforms(Transform root, Transform clone)
{
    foreach (Transform child in root)
    {
        Transform cloneChild = clone.Find(child.name);
        if (cloneChild != null)
        {
            cloneChild.position = child.position;
            cloneChild.rotation = child.rotation;

            MatchAllChildTransforms(child, cloneChild);
        }
    }
}

Thanks for your time!

1 Like

I suppose it’s a little bit of Hugo’s way of doing it, and a slight optimisation. In your version, you have to Find through all transforms of the model, while Hugo’s only Find though the direct parent of the child transform, i.e., you search through the whole person for the ‘left index finger’, while Hugo only searches through the ‘left hand’ for it. But if your version is what you understand better and want to use, go ahead and do it. In this case, the difference in performance is so negligible that you probably won’t notice.

3 Likes

Either way works. The goal is to ensure that every Transform on the Ragdoll corresponds with every Transform on the original character.

Recursion is a powerful tool, when used correctly (such as this). Without a complete profile, it would be difficult to say which method is more efficient. One optimization I might make on yours is to work on the GetComponentsInChildren directly

foreach (Transform childTransform in GetComponentsInChildren<Transform>()

A lot of programmers learn to fear or avoid recursion because of bad experiences from accidental recursion… Here’s a great example of this:

float currentHealth;
public float CurrentHealth
{
    get => CurrentHealth;
}

This simple typo, returning CurrentHealth, the name of the property instead of currentHealth, the name of the field will cause your game to be completely unresponsive until Unity either stops the game or crashes. This is infinite recursion. What @CodeMonkey is using in his method is controlled recursion. We know the method will end, because even with the largest heirarchies, we’ll eventually run out of transforms.

4 Likes

Been there, done that! I created two methods and they were named close enough where one accidentally called itself rather than the other and Unity just kept crashing until I figured it out. haha

1 Like

I think of it as a rite of passage. It’s better than it used to be. I once locked up a Mainframe computer with a recursive method. It was the 1985 equivalent of bringing down the internet.

4 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms