Incorrect root motion magnitude when child animator uses OnAnimatorMove()

I’ve finally narrowed this down after a few days of trying.

Here’s the setup on Unity 2019.4.4f1:

Parent Object with PlayableDirector

  • Child Object with Animator and OnAnimatorMove script that sets the parent’s transform.position

Playable director has one animation track that’s bound to the animator on the child. Dirt simple.
Avatar has a human scale of 1 and all bones/transform have 1,1,1 scale.

Expected amount of movement for this animation is about 1-2 units back on the z. Actual amount moved is instead 147 units back.
Here’s a video of the playable vs the animgraph of the same animation:

Script that sets the parent’s transform based on the root motion:

[ExecuteAlways]
[RequireComponent(typeof(Animator))]
public class ForwardRootMotionToDebug : MonoBehaviour
{
    public Animator Anim;

    // Animator callback
    public void OnAnimatorMove()
    {)
            transform.parent.position += Anim.deltaPosition;
    }
}

My character’s setup in my actual game is fairly unique and I cannot move the animator to the root. Is there any workaround for this?

EDIT: Doesn’t seem to matter where the playabledirector is. Can be on the child, external, parent, etc. Always the same result.

EDIT 2: Dividing the deltaPosition by Time.delta gives somewhat more “normal” magnitudes, but the root motion is still completely out of sync with the animation.

EDIT 3: Using FixedUpdate and pulling the animator.RootPosition results in the same bad magnitudes.

1 Like

Timeline root motion is not the same as the animator. Timeline writes absolute values, not deltas (like the animator) so the deltaPosition you are getting is likely a result of that - it is applying a large ‘delta’ from 0,0,0 on the first frame of the timeline. You can try changing your animation track Track Offsets to ApplySceneOffsets, which may or may not make a difference. Even in that case, timeline is faking a delta by applying the scene position as a track offset prior to execution.

3 Likes

Yep, that does it. Thanks.

Hi,
I have to ask, because even thought it works now (I had a pretty similar setup with the same problem), it defeats the “apply Transform offset” functionnality to place my Animator precisely where I want in the scene. Since it’s a Timeline implying 2 Animators fighting each other, it’s pretty important to keep this functionnality.
Should I place the animators’ parents myself before launching the timeline? or should I find a workaround while keeping the Transform offsets?

1 Like