Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Inverse Kinematics relative to ... ?

Discussion in 'Animation' started by rrh, Nov 21, 2014.

  1. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    So I'm trying my hand at Inverse Kinematics, but the thing I notice is if I add something like a bounce motion or tilting, then the IK goes to the wrong position. Like, it goes to what would have been the correct position without the other animation applied, but offset the same distance as the bounce motion.

    So for example I have something like this, where I have a hand holding a spoon.
    Code (csharp):
    1.  
    2.     public void OnAnimatorIK()
    3.     {
    4.         animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1.0f);
    5.         animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1.0f);
    6.         if(spoon != null) {
    7.             animator.SetIKPosition(AvatarIKGoal.RightHand,spoon.position);
    8.             animator.SetIKRotation(AvatarIKGoal.RightHand,spoon.rotation);
    9.         }
    10.     }
    11.  
    But if I animate him leaning forward to take a bite from the spoon every time it's close, that leaning forward makes the hand leave the spoon.
    cereal.gif

    Is there a way to compensate for this that I'm unaware of?
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    It hard to tell without seeing your controller,
    one hint could be that you are using multiple layer in your controller, in this case you need to specify which layer has an IK pass, and of course the layer with the leaning forward animation should have the IK pass checked.
    Also you want to to setup your IK goal only on this layer. If you leaning forward animation is on layer 1 then modify your code like this
    Code (CSharp):
    1.  
    2. public void OnAnimatorIK(int layerIndex)
    3. {
    4.         if(layerIndex==1)
    5.         {
    6.             animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1.0f);
    7.             animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1.0f);
    8.             if(spoon != null)
    9.             {
    10.                 animator.SetIKPosition(AvatarIKGoal.RightHand,spoon.position);
    11.                 animator.SetIKRotation(AvatarIKGoal.RightHand,spoon.rotation);
    12.             }
    13.      }
    14. }
     
  3. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    I was only using the base layer, but since you mentioned I've tried the multiple layers. I tried IK layer as layer 1 and Animation Layer as Layer 2 and then switched it the opposite order.
    This is what it looks like with IK on Layer 2, anything jump out as suspect?
    I have also tried the IK Layer as Override.

    animationExample.png
     
  4. Aliraza142

    Aliraza142

    Joined:
    Nov 27, 2014
    Posts:
    1
    It hard to tell without seeing your controller, http://www.pass-4sure.us/ does both animator use the same controller?

    If not, does the transition to play this animation have exactly the same condition and timing?
     
  5. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    rrh, can you log a bug please and we will take a look

    Best regards,
     
  6. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    There are no transitions, only one animation playing on a loop.

    I don't think it's a bug with Unity, I still think it's something I'm overlooking, because I haven't the experience with IK.

    You can see in the image Soldier@t-pose because I tried it with a Mixamo model to confirm it wasn't that I didn't rig properly, and the same problem happens with the soldier. That I repeat it both times, I can't believe it's a bug and not something I'm doing wrong.

    Could it be a masking thing? The rig is imported as humanoid, and I did try out a mask at some point, but I hadn't tried every combination in terms of I could apply a mask to the animation layer that ignores the one arm, or maybe apply the opposite mask to the IK layer?

    I could kluge together something where I store the resting position of the shoulder, and use the difference between that and the current shoulder position to offset the spoon position. But people are combining animations with IK all the time. There has to be a simpler method that I'm just unaware of.
     
  7. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    It should work if you only have one layer since the IK is evaluated after the animation.

    So if you can please log a bug with your project and we will take a look. PM your case number
     
  8. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The problem come from your animation clip EatingLoop. You are using a generic clip to animate your humanoid avatar.

    To understand why it doesn't work you need to know what the animator evaluation pipeline look like.

    Evaluate State Machine
    Evaluate clips
    Retarget humanoid clip
    Write transform for first IK pass
    for each layer with IK -> Evaluate IK pass, Write transform
    Write generic transform animation.

    So basically you are overwriting your IK pass with your generic animation.
    Simply keyframe the same clip 'EatingLoop' in blender and import as a humanoid. And replace your old clip in the controller with this new one.


    Also you don't need to have Base Layer, Animation Layer and IK layer. You could all do this in your base layer.
     
  9. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    I originally did it all in the base layer, and only made them separate layers while casting around for possible solutions.

    So no way to make a humanoid animation clip in Unity? I'd been doing all my animation in Unity so I could put off learning to animate in Blender, but if it's necessary for advanced features I guess I'll have to learn.
     
  10. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    No unfortunatelly it's not possible to keyframe a humanoid clip in unity right now. We would need to write a complete humanoid keyframing tools like you can found in blender, max or maya