Search Unity

Adding IK to the legs without affecting underlying animation.

Discussion in 'Animation' started by petey, Sep 5, 2018.

  1. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Hi there,

    I'm stuck with this, basically, I'd like to be able to move the hips of my character a little and preserve the underlying walk animation. So the legs would squash a little but the feet would keep contacting the same position and rotation, is that possible I can't figure it out :(



    Thanks,
    Pete
     
  2. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Okay I managed to get the position to work, but it feels a bit hacky and doesn't work with rotation at all.

    Here's my code, I don't now how I can just alter the hip pos directly so I'm offsetting the foot pos based on it's movement. Does anyone have any experience with this stuff?

    Code (CSharp):
    1.     void OnAnimatorIK(int layerIndex)
    2.     {
    3.         //Left
    4.         //Get pos and rotation of feet
    5.         lTarget.position = anim.GetIKPosition(AvatarIKGoal.LeftFoot);
    6.         lTarget.rotation = anim.GetIKRotation(AvatarIKGoal.LeftFoot);
    7.         //Set IK weights
    8.         anim.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1);
    9.         anim.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1);
    10.         //Add the current offset of the character base
    11.         lTarget.position += (hipTarget.position - hipCharacterBase.position);
    12.         //Set the new IK target pos and rotation
    13.         anim.SetIKPosition(AvatarIKGoal.LeftFoot, lTarget.position);
    14.         anim.SetIKRotation(AvatarIKGoal.LeftFoot, lTarget.rotation);
    I want to be able to do this and keep the feet stuck down.
     
    Last edited: Sep 5, 2018
  3. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    One way to accomplish this is to create an additive layer excluding all bones except the hip/root bone. Create 1-3 simple root bone animations and put them into a blend tree. The blend tree allows you to control the rotation angle based on a blend parameter. The additive layer would allow for the existing animation to perform as it does while adding rotation/transformation to the hips/root.
     
  4. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
  5. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Hey @theANMATOR2b, I tried that and it seems to work but this is already 5 extra animation clips and it doesn't include vertical movement.
    @Mecanim-Dev, is there a way to directly transform the hips while keeping the foot animation intact?

     
  6. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Hi @petey

    have you try to simply lower animator.bodyPosition ?
    https://docs.unity3d.com/ScriptReference/Animator-bodyPosition.html

    Code (CSharp):
    1.  
    2. public class OffsetHips : MonoBehaviour
    3. {
    4.     public Vector3 hipsOffset;
    5.  
    6.  
    7.     Animator m_Animator;
    8.     void Start()
    9.     {
    10.         m_Animator = GetComponent<Animator>();
    11.     }
    12.     private void OnAnimatorIK(int layerIndex)
    13.     {
    14.         if (layerIndex == 0)
    15.         {
    16.             m_Animator.bodyPosition += hipsOffset;
    17.  
    18.             //Set IK weights
    19.             m_Animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1);
    20.             m_Animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1);
    21.             m_Animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1);
    22.             m_Animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1);
    23.  
    24.         }
    25.     }
    26. }
     
  7. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Awesome, @Mecanim-Dev! I thought there might have been a way. Thanks for posting the code snippet :)
     
  8. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Hey @Mecanim-Dev, sorry to drag this up but I was wondering if you might have a good suggestion for this.
    I'm just running in to a bit of trouble because if you apply transforms to the .bodyPosition they run local to the mecanim character root, but bodyRotation is local to the hip bone. Is there a way to apply rotations in the root space as well?
    I feel there is probably a good quaternion way to do this but I'm struggling at the moment...

    Thanks!
    Pete
     
  9. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,824
    Hey I think I got it!
    Code (CSharp):
    1. Quaternion originalrotation = m_Animator.bodyRotation;
    2. Quaternion offset = originalrotation *Quaternion.Inverse(referenceRotation.rotation);
    3. m_Animator.bodyRotation = targetTransform.rotation * offset;
    Does that seem okay? Looks like it's doing the trick :)
     
    XenoGaming likes this.