Create your own IK in Unity

Luis Bermudez
Unity3DAnimation
Published in
4 min readJul 17, 2017

--

Sometimes the IK that is built into Unity is not enough. I’m going to show you how to build your own IK script for Unity (or any system). You can apply this IK to any articulated body — fingers, hands, or feet. The IK that I’m going to review is currently used by Unity, Unreal, Panda, and several other game engines. It is called FABRIK.

FABRIK is an iterative method. An iterative method is a method that does not get the solution right away. An iterative method gets closer and closer to the correct solution with more iterations of the method — in other words, iterations of a loop.

Any IK problem has a given articulated body (a set of connected limbs with lengths and angles). The end effector (the position of the endpoint of the final limb) has a start position with a goal position. It might have other goals, such as angles.

Each FABRIK iteration has two main parts.

void FABRIK() {
while( abs(endEffectorPosition — goalPosition) > EPS ) {
FinalToRoot(); // PartOne
RootToFinal(); // PartTwo
}
}

The first part iterates from the final limb to the root limb. For the final limb, you need to change the angle/rotation of the limb to point at the goal position (keeping the inboard position anchored, and letting the outboard position be translated by the angle change). Next, you translate the final limb along the updated angle towards the goal position, until the limb’s outboard position equals the goal position (maintaining the angle, but letting the limb’s inboard position change). That’s pretty much it for the final limb, except that you now need to update the current goal position. The current goal position is now set to the updated inboard position of the final limb.

For each consecutive inboard limb, you do the same thing. To be clear I will outline it. For the current limb, you need to change the angle/rotation of the limb to point towards the current goal position. Next, you translate the current limb along the updated angle towards the current goal position, until the limb’s outboard position equals the current goal position. Finally, you update the current goal position to be equal to the updated inboard position of the current limb.

Repeat these operations until you’ve completed these operations on the root limb. After that, the first part has been completed.

/* Part One */
void FinalToRoot() {
currentGoal = goalPosition;
currentLimb = finalLimb;
while (currentLimb != NULL) {
currentLimb.rotation = RotFromTo(Vector.UP,
currentGoal — currentLimb.inboardPosition);
currentLimb.outboardPosition = currentGoal;
currentGoal = currentLimb.inboardPosition;
currentLimb = currentLimb->inboardLimb;
}
}

The second part iterates in the reverse direction: from the root limb to the final limb. For the root limb, you need to update its inboard position to the root position. This should translate the whole limb (without stretching). That’s pretty much it for the root limb, except that you now need to update the current inboard position. The current inboard position is now set to the updated outboard position of the root limb.

For each consecutive outboard limb, you do the same thing. To be clear I will outline it. For the current limb, you need to update its inboard position to the current inboard position. This should translate the whole limb. That’s pretty much it for the current limb, except that you now need to update the current inboard position. The current inboard position is now set to the updated outboard position of the current limb.

Repeat these operations until you’ve completed these operations on the final limb. After that, the second part has been completed.

/* Part Two */
void RootToFinal() {
currentInboardPosition = rootLimb.inboardPosition;
currentLimb = rootLimb;
while (currentLimb != NULL) {
currentLimb.inboardPosition = currentInboardPosition;
currentInboardPosition = currentLimb.outboardPosition;
currentLimb = currentLimb->outboardLimb;
}
}

Once the first part and the second part have been completed, you have completed the first iteration of the FABRIK method. Continue iterating on part one and two until the end effector is as close as you need it to be to the goal position, defined by some small EPS (epsilon) value.

That’s it! That’s the FABRIK method. Part One iterates backwards from the final limb. Part Two iterates forward from the root limb. The FABRIK method iterates Part One and Part Two until the end effector is close enough to the goal position.

If any IK jargon did not make sense, please review my Overview of Inverse Kinematics.

If you enjoyed this article, please to help others find it!

I would like to thank Ivan Bindoff and Pärtel Lang for contributing their valuable feedback in this article.

--

--