All Classes Namespaces Functions Variables Enumerations Properties Pages
Full Body Biped IK

Final IK includes an extremely flexible and powerful high speed lightweight FBIK solver for biped characters.

FullBodyBipedIK maps any biped character to a low resolution multi-effector IK rig, solves it, and maps the result back to the character. This is done each frame in LateUpdate, after Mecanim/Legacy is done animating, so it is completely independent from the animating system.

Chains: Internally, each limb and the body are instances of the FBIKChain class. The root chain is the body, consisting of a single node, and the limbs are its children. This setup forms the multi-effector IK tree around the root node.

Nodes: Nodes are members of the Chains. For instance, an Arm chain contains three nodes - upper arm, forearm and the hand. Each node maintains a reference to its bone (node.transform). When the solver is processing or has finished, the solved position of the bone is stored in node.solverPosition.

Effectors: FullBodyBipedIK has three types of effectors - end-effectors (hands and feet), mid-body effectors (shoulders and thighs) and multi-effectors (the body). End-effectors can be rotated while changing the rotation of mid-body and multi-effectors has no effect. Changing end-effector rotation also changes the bending direction of the limb (unless you are using bend goals to override it). The body effector is a multi-effector, meaning it also drags along both thigh effectors (to simplify positioning of the body). Effectors also have the positionOffset property that can be used to very easily manupulate with the underlaying animation. Effectors will reset their positionOffset to Vector3.zero after each solver update.

Pulling, Reaching and Pushing: Each chain has the "pull" property. When all chains have pull equal to 1, pull weight is distributed equally between the limbs. That means reaching all effectors is not quaranteed if they are very far from each other. The result can be adjusted or improved by changing the "reach" parameter of the chain, increasing the solver iteration count or updating the solver more than once per frame. However, when for instance the left arm chain has pull weight equal to 1 and all others have 0, you can pull the character from its left hand to Infinity without losing contact. The Push and Push Parent values determine how much a limb transfers energy to its parent nodes when the target is in reach. Experiment with those values in the Scene view to get a better understanding of how they behave.

Mapping: IKSolverFullBodyBiped solves a very low resolution high speed armature. Your character probably has a lot more bones in its spine though, it might have twist bones in the arms and shoulder or hip bones and so on. Therefore, the solver needs to map the high resolution skeleton to the low resolution solver skeleton before solving and vice versa after the solver has finished. There are 3 types of mappers - IKMappingSpine for mapping the pelvis and the spine, IKMappingLimb for the limbs (including the clavicle) and IKMappingBone for the head. You can access them through IKSolverFullBody.spineMapping, IKSolverFullBody.limbMappings and IKSolverFullBody.boneMappings

FullBodyBipedIK.png
Retargeting a single punching animation with FullBodyBipedIK

Limitations:


Getting started:


Accessing the Effectors:

public FullBodyBipedIK ik;
void LateUpdate () {
ik.solver.leftHandEffector.position = something; // Set the left hand effector position to a point in world space. This has no effect if the effector's positionWeight is 0.
ik.solver.leftHandEffector.rotation = something; // Set the left hand effector rotation to a point in world space. This has no effect if the effector's rotationWeight is 0.
ik.solver.leftHandEffector.positionWeight = 1f; // Weighing in the effector position, the left hand will be pinned to ik.solver.leftHandEffector.position.
// Weighing in the effector rotation, the left hand and the arm will be pinned to ik.solver.leftHandEffector.rotation.
// Note that if you only wanted to rotate the hand, but not change the arm bending,
// it is better to just rotate the hand bone after FBBIK has finished updating (use the OnPostUpdate delegate).
ik.solver.leftHandEffector.rotationWeight = 1f;
// Offsets the hand from its animated position. If effector positionWeight is 1, this has no effect.
// Note that the effectors will reset their positionOffset to Vector3.zero after each update, so you can (and should) use them additively.
//This enables you to easily edit the value by more than one script.
ik.solver.leftHandEffector.positionOffset += something;
//The effector mode is for changing the way the limb behaves when not weighed in.
//Free means the node is completely at the mercy of the solver.
//(If you have problems with smoothness, try changing the effector mode of the hands to MaintainAnimatedPosition or MaintainRelativePosition
//MaintainAnimatedPosition resets the node to the bone's animated position in each internal solver iteration.
//This is most useful for the feet, because normally you need them where they are animated.
//MaintainRelativePositionWeight maintains the limb's position relative to the chest for the arms and hips for the legs.
// So if you pull the character from the left hand, the right arm will rotate along with the chest.
//Normally you would not want to use this behaviour for the legs.
ik.solver.leftHandEffector.maintainRelativePositionWeight = 1f;
// The body effector is a multi-effector, meaning it also manipulates with other nodes in the solver, namely the left thigh and the right thigh
// so you could move the body effector around and the thigh bones with it. If we set effectChildNodes to false, the thigh nodes will not be changed by the body effector.
ik.solver.body.effectChildNodes = false;
// Other effectors: rightHandEffector, leftFootEffector, rightFootEffector, leftShoulderEffector, rightShoulderEffector, leftThighEffector, rightThighEffector, bodyEffector
// You can also find an effector by:
ik.solver.GetEffector(FullBodyBipedEffector effectorType);
ik.solver.GetEffector(FullBodyBipedChain chainType);
ik.solver.GetEndEffector(FullBodyBipedChain chainType); // Returns only hand or feet effectors
}


Accessing the Chains:

public FullBodyBipedIK ik;
void LateUpdate () {
ik.solver.leftArmChain.pull = 1f; // Changing the Pull value of the left arm
ik.solver.leftArmChain.reach = 0f; // Changing the Reach value of the left arm
// Other chains: rightArmChain, leftLegChain, rightLegChain, chain (the root chain)
// You can also find a chain by:
ik.solver.GetChain(FullBodyBipedChain chainType);
ik.solver.GetChain(FullBodyBipedEffector effectorType);
}


Accessing the Mapping:

public FullBodyBipedIK ik;
void LateUpdate () {
ik.solver.spineMapping.iterations = 2; // Changing the Spine Mapping Iterations
ik.solver.leftArmMapping.maintainRotationWeight = 1f; // Make the left hand maintain its rotation as animated.
ik.solver.headMapping.maintainRotationWeight = 1f; // Make the head maintain its rotation as animated.
}


Adding FullBodyBipedIK in runtime (UMA):

using RootMotion; // Need to include the RootMotion namespace as well because of the BipedReferences
FullBodyBipedIK ik;
// Call this method whenever you need in runtime.
// Please note that FBBIK will sample the pose of the character at initiation so at the time of calling this method,
// the limbs of the character should be bent in their natural directions.
void AddFBBIK (GameObject go, BipedReferences references = null) {
if (references == null) { // Auto-detect the biped definition if we don't have it yet
BipedReferences.AutoDetectReferences(ref references, go.transform, BipedReferences.AutoDetectParams.Default);
}
ik = go.AddComponent<FullBodyBipedIK>(); // Adding the component
// Set the FBBIK to the references. You can leave the second parameter (root node) to null if you trust FBBIK to automatically set it to one of the bones in the spine.
ik.SetReferences(references, null);
// Using pre-defined limb orientations to safeguard from possible pose sampling problems (since 0.22)
ik.solver.SetLimbOrientations(BipedLimbOrientations.UMA); // The limb orientations definition for UMA skeletons
// or...
ik.solver.SetLimbOrientations(BipedLimbOrientations.MaxBiped); // The limb orientations definition for 3ds Max Biped skeletons
// or..
ik.solver.SetLimbOrientations(yourCustomBipedLimbOrientations); // Your custom limb orientations definition
// To know how to fill in the custom limb orientations definition, you should imagine your character standing in I-pose (not T-pose) with legs together and hands on the sides...
// The Upper Bone Forward Axis is the local axis of the thigh/upper arm bone that is facing towards character forward.
// Lower Bone Forward Axis is the local axis of the calf/forearm bone that is facing towards character forward.
// Last Bone Left Axis is the local axis of the foot/hand that is facing towards character left.
}


Solving the head

Final IK 0.5 introduced the FBBIKHeadEffector component that enables us to use the FullBodyBipedIK component to map a character to the target position and rotation of the head. Please take a look at the "Head Effector" demo scene to see how it can be set up.
NB! It is highly recommended to use VRIK instead of FullBodyBipedIK for VR avatars and in other scenarios where head targets are required.


Optimizing FullBodyBipedIK:


Component variables:


Solver variables:


Body variables:


Limb variables:

FullBodyBipedIKComponent.png


Script References: