Search Unity

Question Foot IK for stairs climbing

Discussion in 'Animation' started by Vazili_KZ, Mar 9, 2021.

  1. Vazili_KZ

    Vazili_KZ

    Joined:
    Sep 18, 2016
    Posts:
    25
    Hello guys hope everybody is doing fine and keeping safe.

    I've been working on a foot IK system following a YouTube tutorial.
    But being really new to IK in Unity I'm having problem implementing it with my player. No problem with code or anything i fully understood what it's doing.

    Context :

    I'm trying to implement stairs and I want my player to climb the stairs with the right foot placement.
    The way I'm doing this is I'm creating two duplicate stairs one child of the other, and the parent will be just a ramp that the rigidbody can climb easily, whilst the child is actually a convex collider and is in the layer "Walkable" which means that this is the one the player should place its feet into.

    The Problem :
    Now what's happening is that my feet are not long enough to touch the stairs (Capsule collider not allowing them to) so the player just stays floating in the air.
    and if I rise the capsule collider of the player well then obviously the standing pose will become totally different since his legs will be bent, and that doesn't look good.

    What are your suggestions about how I should implement this, what am I missing here?

    Thank you all for reading this and thanks for your help :D

    Attachments :

    Foot IK code : Pastebin Link

    Figure 1 : Player floating since the collider doesn't allow the legs to reach the ground


    Figure 2 : Legs bent due to attempting to rise the collider even more. Obviously not a good idea...
     
  2. Vazili_KZ

    Vazili_KZ

    Joined:
    Sep 18, 2016
    Posts:
    25
    UPDATE :
    I managed to fix my problem so I'll be sharing the solution for anyone who might find this useful and also if anyone have ideas on how to improve it or do it in a more efficient way please share with us.

    Changes :
    1. added a checkDistance and feetOffset rather then the old distanceToGround so that i can cast further with the "checkDistance" and be more precise when placing the foot with "feetOffset". Don't know why I didn't do this from the beginning it seems pretty obvious actually :p.

    2. and the is THE MAIN thing that was missing : "Hips Movement"
    I moved the hips down whenever the feet can't reach the ground because of the capsule collider. this way the feet can now comfortably sit on the ground.
    I do so by calculating by how much each foot needs to move, and then select the biggest value of the two and move the hips by that amount down or up depending on whether the feet are moving down or up.



    As you can see the capsule is still in it's place like it should be, it's just the model that's moving (his hips).

    3. With that in place, I'm faced with a new problem now :


    Players feet going inside the stairs because we determined that they should be placed at that position with our raycast.

    In order to fix that, I added a second raycast with a forward offset in the Z axis which correspond to the distance between to foot and the toes.



    Now with two raycasts I first check if the original foot raycast hit something (in this case a step) then great do what we usually do.
    If not, then that means we are on an edge situation where only the toes should be resting on a step.

    To do so, now comes into play the second offset raycast we added. we check if it's hitting a stair, if so then great now let's apply our logic :

    All we need to do now is place that same foot bone but not on the hit point, rather we apply a Z offset in the negative direction (the same offset we used for the second ray ie: the foot-toes distance).
    And like so we achieve the desired behaviour :


    (In this image it's only applied to the left foot. I was just testing so of course later on I added the same logic for the other foot.)

    And now this is the end result :



    Hope this logic made sense to you.
    I would love to hear some ideas especially from people who have already implemented this kind of system, because this is just my way of doing it but I'd love to know what the industry standard is in tackling this subject.

    Thank you all for reading :D

    Attachment :

    Updated Foot IK code : Pastebin Link
     
    matiasges and bobadi like this.
  3. Vazili_KZ

    Vazili_KZ

    Joined:
    Sep 18, 2016
    Posts:
    25
    Update :

    Found some bugs with this system, the way i had it earlier made me unable to place feet correctly in slope, so it's either precise foot placement for stairs and no placement in slope, or a generic solution for both but it's not so precise in stairs but it still looks nice.

    I choose the second option and here is my final code : Pastebin Link.

    Hope one of the more experienced of you guys can help me with this and show me the best approach to tackle this.

    Thank you once again and have a good day.
     
    matiasges likes this.
  4. matiasges

    matiasges

    Joined:
    Jan 24, 2021
    Posts:
    142
    Hi. Thanks for the code! :)

    I got a problem maybe you have an idea?

    In the lines:

    Code (CSharp):
    1. _animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, _animator.GetFloat("IKLeftFootWeight"));
    2.             _animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, _animator.GetFloat("IKLeftFootWeight"));
    3.             _animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, _animator.GetFloat("IKRightFootWeight"));
    4.             _animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, _animator.GetFloat("IKRightFootWeight"));
    The IKRightFootWeight or LeftFootWeight is not working. It only works when I set it to 1. So, with something like this it is working:

    Code (CSharp):
    1.  
    2. _animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1f);
    3.            
    The only problem with this is that after the character climb the stairs he will end up with that position when walking... it's strange