Search Unity

Can't get Root Motion

Discussion in 'Scripting' started by AnimusRex, Apr 28, 2020.

  1. AnimusRex

    AnimusRex

    Joined:
    Apr 26, 2019
    Posts:
    67
    I'm trying to apply root motion for attack animations, but not other animations.

    Doing debug logs, my anim.deltaPosition is always 0,0,0, and my root motion is always off, and I can't figure out why.

    Here is my StateManager:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using InControl;
    5. namespace KM
    6. {
    7.     public class StateManager : MonoBehaviour
    8.     {
    9.         [Header("Init")]
    10.         public GameObject activeModel;
    11.         [Header("Inputs")]
    12.         public float vertical;
    13.         public float horizontal;
    14.         public float moveAmount;
    15.         public Vector3 moveDir;
    16.         public bool l1, l2, r1, r2;
    17.         public bool twoHanded;
    18.         [Header("Stats")]
    19.         public float moveSpeed = 2f;
    20.         public float runSpeed = 3.5f;
    21.         public float rotateSpeed = 8f;
    22.         public float toGround = 0.5f;
    23.         [Header("States")]
    24.         public bool onGround;
    25.         public bool run;
    26.         public bool lockOn;
    27.         public bool inAction;
    28.         public bool canMove;
    29.         public bool isTwoHanded;
    30.         [HideInInspector]
    31.         public AnimatorHook a_hook;
    32.         [HideInInspector]
    33.         public Animator anim;
    34.         [HideInInspector]
    35.         public Rigidbody rigid;
    36.         [HideInInspector]
    37.         public float delta;
    38.         [HideInInspector]
    39.         public LayerMask ignoreLayers;
    40.         float _actionDelay;
    41.         public void Init()
    42.         {
    43.             SetupAnimator();
    44.             rigid = GetComponent<Rigidbody>();
    45.             rigid.angularDrag = 999;
    46.             rigid.drag = 4;
    47.             rigid.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
    48.             a_hook = activeModel.AddComponent<AnimatorHook>();
    49.             a_hook.Init(this);
    50.             gameObject.layer = 8;
    51.             ignoreLayers = ~(1 << 9);
    52.             anim.SetBool("onGround", true);
    53.         }
    54.         void SetupAnimator()
    55.         {
    56.             if (activeModel == null)
    57.             {
    58.                 anim = GetComponentInChildren<Animator>();
    59.                 if (anim == null)
    60.                 {
    61.                     Debug.Log("You're a dingus, there's no model");
    62.                 }
    63.                 else
    64.                 {
    65.                     activeModel = anim.gameObject;
    66.                 }
    67.             }
    68.             if (anim == null)
    69.                 anim = activeModel.GetComponent<Animator>();
    70.             anim.applyRootMotion = false;
    71.         }
    72.         public void FixedTick(float d)
    73.         {
    74.             delta = d;
    75.             DetectAction();
    76.             if (inAction)
    77.             {
    78.                 _actionDelay += delta;
    79.                 if(_actionDelay > 0.3f)
    80.                 {
    81.                     inAction = false;
    82.                     _actionDelay = 0;
    83.                 }
    84.                 else
    85.                 {
    86.                     return;
    87.                 }
    88.             }
    89.             canMove = anim.GetBool("can_move");
    90.             if (!canMove)
    91.             {
    92.                 return;
    93.             }
    94.             anim.applyRootMotion = false;
    95.             rigid.drag = (moveAmount > 0 || onGround == false) ? 0 : 4;
    96.             float targetSpeed = moveSpeed;
    97.             if (run)
    98.                 targetSpeed = runSpeed;
    99.             if(onGround)
    100.             rigid.velocity = moveDir * (targetSpeed * moveAmount);
    101.             if (run)
    102.                 lockOn = false;
    103.             if (!lockOn)
    104.             {
    105.                 Vector3 targetDir = moveDir;
    106.                 targetDir.y = 0;
    107.                 if (targetDir == Vector3.zero)
    108.                     targetDir = transform.forward;
    109.                 Quaternion tr = Quaternion.LookRotation(targetDir);
    110.                 Quaternion targetRotation = Quaternion.Slerp(transform.rotation, tr, delta * moveAmount * rotateSpeed);
    111.                 transform.rotation = targetRotation;
    112.             }
    113.             HandleMovementAnimations();
    114.         }
    115.         public void DetectAction()
    116.         {
    117.             if (!canMove)
    118.                 return;
    119.             if (!r1 && !r2 && !l1 && !l2)
    120.                 return;
    121.             string targetAnim = null;
    122.             if (r1)
    123.                 targetAnim = "oh_attack_1";
    124.             if (r2)
    125.                 targetAnim = "oh_attack_3";
    126.             if (l1)
    127.                 targetAnim = "oh_attack_1";
    128.             if (l2)
    129.                 targetAnim = "oh_attack_2";
    130.             canMove = false;
    131.             inAction = true;
    132.             anim.CrossFade(targetAnim, 0.2f);
    133.         }
    134.         public void Tick(float d)
    135.         {
    136.             delta = d;
    137.             onGround = OnGround();
    138.             anim.SetBool("onGround", onGround);
    139.         }
    140.         void HandleMovementAnimations()
    141.         {
    142.             anim.SetBool("run", run);
    143.             anim.SetFloat("vertical", moveAmount, 0.4f, delta); //Only vertical because no lock on mode
    144.         }
    145.         public bool OnGround()
    146.         {
    147.             bool r = false;
    148.             Vector3 origin = transform.position + (Vector3.up * toGround);
    149.             Vector3 dir = -Vector2.up;
    150.             float dis = toGround + 0.3f;
    151.             RaycastHit hit;
    152.             if(Physics.Raycast(origin, dir, out hit, dis, ignoreLayers))
    153.             {
    154.                 r = true;
    155.                 Vector3 targetPosition = hit.point;
    156.                 transform.position = targetPosition;
    157.             }
    158.             Debug.DrawRay(origin, dir, Color.red);
    159.             return r;
    160.         }
    161.         public void HandleTwoHanded()
    162.         {
    163.             anim.SetBool("two_handed", isTwoHanded);
    164.         }
    165.     }
    166. }
    And here is my animator hook;
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. namespace KM
    5. {
    6.     public class AnimatorHook : MonoBehaviour
    7.     {
    8.         Animator anim;
    9.         StateManager states;
    10.         public void Init(StateManager st)
    11.         {
    12.             states = st;
    13.             anim = st.anim;
    14.         }
    15.         void OnAnimatorMove()
    16.         {
    17.             Vector3 DeltaPosition = anim.deltaPosition;
    18.             Vector3 OriginalVelocity = states.rigid.velocity;
    19.             Vector3 SetVelocity = DeltaPosition / Time.deltaTime;
    20.             //Add new velocity
    21.             states.rigid.velocity = SetVelocity;
    22.         }
    23.         void OpenDamageColliders()
    24.         {
    25.         }
    26.         void CloseDamageColliders()
    27.         {
    28.         }
    29.     }
    30. }
    If anyone has any insight I'd love to know, I've been stuck on this for a few days with no resolution in sight. It looks like something in how root motion is set changed around 2018, and most of the solutions I'm finding are before the change.