Search Unity

Question Calculation of root motion

Discussion in 'Animation' started by Galimatias23, Jan 12, 2023.

  1. Galimatias23

    Galimatias23

    Joined:
    Jan 12, 2023
    Posts:
    2
    I have access to relatively big packet of humanoid animations (typical cases like walking, idling, running) but they don't have any root motion. They are both in-air and in-place. So if animation jumps, the model doesn't get any higher, and if animation crouches, legs go up into the air and model floats above ground.

    I was wondering if there is any way to calculate root motion based solely on those movements. I was looking for some AI based papers, IK scripts, etc. yet without success (also, I'm not sure exactly what phrases should I look for). Full root motion is not necessary - "grounding" model to the floor would be enough. I've programmed some scripts which successfully "grounded" model to the floor, but I have no idea how to detect jumps, and model is constantly "glued" to the floor which looks very unnatural and "glitchy".

    Any ideas on the topic? :)
     
  2. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    674
    I have a script for in-place animations which can be used to move root transform based on anchor (left or right foot).
    haven't used it for a long time, but it goes like
    you should check that during the animation which foot is on ground, for how long, and set those normalized times
    and the root will be moved based on that

    let me know how it goes
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class rootShift : MonoBehaviour {
    6.  
    7.     public Animator animator;
    8.     public AnimatorStateInfo animStateInfo;
    9.     public float NTime;
    10.  
    11.     [HideInInspector] public Vector3 offset0;//root anchor : rootP
    12.  
    13.     public Transform[] T;//the root anchor
    14.  
    15.     public float[] nTimeStart;
    16.     public float[] nTimeEnd;
    17.     [HideInInspector] public int x;//T anchor based on nTime
    18.     int i;
    19.     [HideInInspector] public Vector3[] TPX;
    20.  
    21.     public Vector3 newP;
    22.  
    23.  
    24.     void Start () {
    25.  
    26.         TPX = new Vector3[T.Length];
    27.     }
    28.  
    29.  
    30.     void Update () {
    31.  
    32.         animStateInfo = animator.GetCurrentAnimatorStateInfo (0);
    33.         NTime = animStateInfo.normalizedTime;
    34.         NTime = NTime % 1;
    35.  
    36.         for (i = 0; i < T.Length; i++) {
    37.  
    38.             if (NTime > nTimeStart [i] && NTime < nTimeEnd [i]) {
    39.                 x = i;
    40.                 if(TPX[x] == Vector3.zero) TPX[x] = T [x].position;
    41.             }
    42.         }
    43.  
    44.  
    45.     }
    46.  
    47.     void OnAnimatorMove(){
    48.  
    49.  
    50.         animator.ApplyBuiltinRootMotion ();
    51.  
    52.         offset0 = T [x].position - animator.rootPosition;
    53.     }
    54.  
    55.  
    56.     void LateUpdate () {
    57.  
    58.  
    59.             newP = TPX[x] - offset0;
    60.             newP.y = 0;
    61.  
    62.         animator.rootPosition = newP;
    63.  
    64.     }
    65.  
    66. }
     
    Last edited: Jan 13, 2023
  3. Galimatias23

    Galimatias23

    Joined:
    Jan 12, 2023
    Posts:
    2
    Thanks! That will be usefull (but later). My issue is, that feets are not exactly on the ground. If someone crouches, the feet would be like 50 cm over the ground level...
     
  4. bobadi

    bobadi

    Joined:
    Jan 3, 2019
    Posts:
    674