Foot IK System Without Weight Curves?

Hello all,

I’ve finally created a foot placement IK solution for mecanim that works pretty well, but there’s one step that could pose an issue later in development: creating curves for IK weights.

The system works similar to most setups you can find in tutorials: A raycast is shot from the foot to find the floor point, then the IKPosition is set to that point. Weights are set based on an Animator Parameter which is driven by Animation curves for the walking animations. However, I have to set these curves manually on import in the animation window. This can get pretty tedious considering I may have a lot of animations, most of them standing still. I’ve been trying to find a way to automate the IK weights without manually specifying the curves, but I can’t find any solutions.

Potential Solutions:

  • Detecting the Y position of the foot and comparing it to an initial position to see if it’s on the “ground”. However, once the foot position has been set by the IK, it will get caught in an infinite loop, since it will never be above the ground level due to the Y position being set by the IK. If there was a way to get the Pre-IK position, I could use this to determine the weights, but I’ve not seen an option for that.

  • As an extension of the previous idea, if I had 2 animators or 2 layers running in sync, I could get the foot position of one of them without an IK pass and use that as the Pre-IK data, and set the weights for the other one (the “final” animation).

  • Detecting the current animation “state”, and ignoring curves to just set the weights to a constant. This would mean manually inputting (or hardcoding) which animations should use curves and which should ignore them, but it’s still less work than making curves for every animation.

Thoughts appreciated!

Forgive my lack of knowledge. Are the weights values given to the object to decide which target to lock onto.

The process I use outside of Unity is to simply use IK weighting on/off over one keyframe. Either the IK is on and the object is parented to the target (I’ve chosen) or the IK is off and the animation is controlling the object.
So if I’m IKing a hand to a surface I’ll animate the hand up to the point where I want the hand to lock onto over a set amount of keyframes (IK is off during this animation). At the moment I want the hand to lock to the surface, I turn on IK, and set the target to the surface. So IK is off at keyframe 22 and turned on at keyframe 23. The hand is locked to the surface until I turn IK off.

Another common example is a fps setup. The left hand is IK locked to the rifle which is parented to the right hand. Also in this setup is a magazine which is parented to the rifle.
When the bullets run out, the left hand IK is turned off, the hand is animated to the magazine and the magazine changes parents from the rifle to the left hand. The left hand performs the change mag animation and then re-positions back onto the rifle - at which point IK is turned back on.

I know Unity IK is different - but thought these examples of IK use may aid in sparking an idea to solve the weight issue you mention.

1 Like

Thanks for the info, but the real issue is that I’m dealing with an IK walk cycle. The problem is not turning on and off the IK, the problem is that manually specifying when the IK is “on” (weight of 1) is tedious to set up using animation curves. The “weights,” which I specified with these curves, run in sync to the animation, which I then read from a script to input to Animator.SetIKPositionWeight. I had wished to devise a system that automates this process, so I don’t have to make curves for every animation.

As it happens, I’ve found a solution, albeit a hacky one. I’ve been setting the weights in the OnAnimatorIK callback (which happens every frame), and realized if I set the IKPositionWeight to 0, I can quickly retrieve the “pre-IK” position. Then at the end of the function, I just set the weights back to what they would be. This way of getting the position is actually very consistent. I then used the original (Pre-IK) animation position to determine the foot’s Y position. If it was below a certain threshold, the weights increase (the foot is on the ground). Since I am negating the IK every time I read this info, it never gets caught in an infinite loop.

For anyone else who stumbles upon this issue, here’s a quick code example:

void OnAnimatorIK (int layer) {
    anim.SetIKPositionWeight(rightfoot, 0);
    //This is the position BEFORE IK is applied
    Vector3 preposition = rightfoot.transform.position;
    anim.SetIKPositionWeight(rightfoot, 1);
    //This is the position AFTER IK is applied
    Vector3 postposition = rightfoot.transform.position;
}
4 Likes

Hello there,

this is an old post, but I want to suggest another solution. It also should be possible, to check the speed of the feet and release the weight depending on the speed. I think it is important not to set the weight to 100%, that the feet keep stuck to the ground. If you’re using the speed of the feet also think about using AnimatonCurves in the script, where you control the weight of the feet. This could help to get a quick and defined release of the foot, if it’s moving.

Using AnimationCurves is the typical way to do it, but the point of this post was to find a way to automate that process and eliminate the need to define it for every animation. By detecting the Y value (height) of the foot before IK is applied, I was able to tell when the animation of the foot is “on the ground” and when it’s in the air. Of course it puts a restriction on your animation: feet below a certain height are always considered grounded. In practice I used a few more conditions to guide when IK is enabled or disabled, like detecting if the player controller is airborne or in a special animation. Combining both of these ideas allowed for good control over when it’s applied.

Using speed could also work in some situations but I’d see a problem with it if your feet started moving slowly but above ground level, say for a “falling” animation. And I think it’s harder to visualize that way, but whatever works for you is what you should go with. Being able to get the pre-IK position thanks to the snippet I posted above allows for all of these techniques to work.

1 Like