Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We’re making changes to the Unity Runtime Fee pricing policy that we announced on September 12th. Access our latest thread for more information!
    Dismiss Notice
  3. Dismiss Notice

Incorrect root motion magnitude when child animator uses OnAnimatorMove()

Discussion in 'Timeline' started by Reticulatas, Aug 9, 2020.

  1. Reticulatas

    Reticulatas

    Joined:
    Jul 31, 2012
    Posts:
    25
    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:

    Code (CSharp):
    1. [ExecuteAlways]
    2. [RequireComponent(typeof(Animator))]
    3. public class ForwardRootMotionToDebug : MonoBehaviour
    4. {
    5.     public Animator Anim;
    6.  
    7.     // Animator callback
    8.     public void OnAnimatorMove()
    9.     {)
    10.             transform.parent.position += Anim.deltaPosition;
    11.     }
    12. }
    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.
     
    Last edited: Aug 9, 2020
    Menion-Leah likes this.
  2. seant_unity

    seant_unity

    Unity Technologies

    Joined:
    Aug 25, 2015
    Posts:
    1,516
    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.
     
    davidrochin, floky and Reticulatas like this.
  3. Reticulatas

    Reticulatas

    Joined:
    Jul 31, 2012
    Posts:
    25
    Yep, that does it. Thanks.
     
  4. unity_kPFmHCTONM1I6Q

    unity_kPFmHCTONM1I6Q

    Joined:
    Jan 16, 2020
    Posts:
    1
    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?
     
    Last edited: Jan 24, 2023
    Alic likes this.