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 have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

(VRIK) Best way to re-target generic hand model animations to Humanoid character hands

Discussion in 'General Discussion' started by minsuthekoiwi, Sep 16, 2020.

  1. minsuthekoiwi

    minsuthekoiwi

    Joined:
    Jul 19, 2019
    Posts:
    1
    What I want to achieve is to be able to re-target generic hand model animations to Humanoid character hands.

    I am currently testing this with the hand model provided by Oculus (hand_skeletal_lowres) and a character model called racer from Mixamo. Ideally you would be able to do this with any custom hand model (E.g hand model with 3 fingers) and any custom character model.

    After some research I have found out that in order to achieve this you either create hand animation using humanoid character and add a layer with hand mask in the animation controller (VR Chat has done this)
    or apply the rotation of each finger bones to and then apply some rotation offset again like this guy

    https://forum.unity.com/threads/oculus-handtracking-with-custom-hand-model.810678/

    I have tried both methods and the second method ended up giving me the better result

    Here is the helper class I created for second method



    public class HandSkeletonHelper : MonoBehaviour
    {

    [System.Serializable]
    public class Retargetable
    {
    public Transform source;
    public Transform destination;
    public Vector3 offset;

    public Retargetable(Transform source, Transform destination, Vector3 offset)
    {
    this.source = source;
    this.destination = destination;
    this.offset = offset;
    }
    }

    [System.Serializable]
    public class Finger
    {
    public Retargetable bone1;
    public Retargetable bone2;
    public Retargetable bone3;
    public Retargetable bone4;

    public Finger(Retargetable bone1, Retargetable bone2, Retargetable bone3, Retargetable bone4)
    {
    this.bone1 = bone1;
    this.bone1 = bone2;
    this.bone1 = bone3;
    this.bone4 = bone4;
    }
    }

    public Retargetable wrist;
    public Finger[] fingers;

    // Update is called once per frame
    void Update()
    {
    for (int fingerIndex = 0; fingerIndex < fingers.Length; fingerIndex++)
    {
    Finger finger = fingers[fingerIndex];
    //finger.bone1.destination.localRotation = finger.bone1.source.localRotation;
    finger.bone1.destination.rotation = finger.bone1.source.rotation;
    finger.bone1.destination.Rotate(finger.bone1.offset);
    //finger.bone2.destination.localRotation = finger.bone2.source.localRotation;
    finger.bone2.destination.rotation = finger.bone2.source.rotation;
    finger.bone2.destination.Rotate(finger.bone2.offset);
    //finger.bone3.destination.localRotation = finger.bone3.source.localRotation;
    finger.bone3.destination.rotation = finger.bone3.source.rotation;
    finger.bone3.destination.Rotate(finger.bone3.offset);
    //finger.bone4.destination.localRotation = finger.bone4.source.localRotation;
    finger.bone4.destination.rotation = finger.bone4.source.rotation;
    finger.bone4.destination.Rotate(finger.bone4.offset);

    }

    //wrist.destination.position = wrist.source.position;
    //wrist.destination.localRotation = wrist.source.localRotation;
    }
    }


    The results look like this

    using LocalRotation without offset


    using LocalRotation with offset


    using Rotation without offset


    using Rotation with offset


    Obviously using rotation with offset achieves what I want but is this really the best way to do it?
    It feels quite hacky and if I were to use different character model, I would have to set the offset for each finger bone all over again.

    If someone knows any better solutions to achieve this, please post it here.
     
  2. DebugLogError

    DebugLogError

    Joined:
    Jul 24, 2013
    Posts:
    54
    @minsuthekoiwi Did you ever find a better solution? I'm looking todo something similar.
     
  3. lucidtripper

    lucidtripper

    Joined:
    Aug 3, 2017
    Posts:
    21