This page is about a beta feature, that may not be stable yet
Introduction
Our SDK allows inverse kinematic control when playing a kinetix animation. The IK has multiple features such as :
Hint (or "Pole Vector"): These are positions like "left knee" or "right elbow" used by the IK to orient the elbow or knee in the correct direction.
Target: These are, as their name suggest, the target position and rotation for a hand or foot.
Auto-retargeted hand and foot rotation : Our IK ensure that if you have multiple rigs in your virtual world, the IK rotation will be the same for both characters.
Adjust Hips : This feature let you lock hands or foots into place by moving the hips
The entire IK api ask for global rotations and positions.
The IK target rotation is described as follow : For the hands, the forward vector points toward the fingers (we average each finger to get a forward direction). The down vector points toward the palm of the hand.
For the feet, the forward vector points toward the toes, parallel to the ground. The down vector points toward the knee. (based on the T-Pose)
The IK target position use the root game object you provide us when registering your avatar in order to convert from global context to the avatar context.
IK Event
Registering the OnBeforeIkEffect allows you bind to the Update of the Kinetix Animator before any IK is computed. This allows you to check for collisions or grounding and use IK methods.
using Kinetix;
using UnityEngine;
public class MyIkTestClass : MonoBehaviour
{
[SerializeField] private Animator myAnimator;
//This code is from the Quickstart example
private void Awake()
{
KinetixCore.OnInitialized += OnInitialize;
KinetixCore.Initialize(new KinetixCoreConfiguration()
{
GameAPIKey = "yourGameAPIKey",
PlayAutomaticallyAnimationOnAnimators = true,
EnableAnalytics = true
});
}
private void OnInitialize()
{
KinetixCore.OnInitialized -= OnInitialize;
//Register local Player
KinetixCore.Animation.RegisterLocalPlayerAnimator(myAnimator);
//Register IK event
KinetixCore.Animation.RegisterIkEventOnLocalPlayer(Kinetix_OnBeforeIK);
}
private void OnDestroy()
{
//"Try" in case the sdk is disposed before us.
//Unregister the event
try
{
KinetixCore.Animation.UnregisterIkEventOnLocalPlayer(Kinetix_OnBeforeIK);
}
finally {}
}
private void Kinetix_OnBeforeIK(IKInfo currentPose)
{
//In this example, every position and locations
//depends on the scene and on the character.
//We can use IK methods here.
//We set the Elbow hint at the left foot position.
KinetixCore.Animation.SetIKHintPositionOnLocalPlayer(AvatarIKHint.LeftElbow, Vector3.left);
//Set target position for the left hand
KinetixCore.Animation.SetIKPositionOnLocalPlayer(AvatarIKGoal.LeftHand, Vector3.left + 2*Vector3.up);
//Set weight between the Animation pose and the IK pose.
KinetixCore.Animation.SetIKPositionWeightOnLocalPlayer(AvatarIKGoal.LeftHand, 1); //1 = full ik
//Make the palm look at the forward (= hand's back look at the back) and make the fingers look up
KinetixCore.Animation.SetIKRotationOnLocalPlayer(AvatarIKGoal.LeftHand, Quaternion.LookRotation(Vector3.up, Vector3.back));
//Set weight between the Animation pose and the IK pose.
KinetixCore.Animation.SetIKRotationWeightOnLocalPlayer(AvatarIKGoal.LeftHand, 1); //1 = full ik
}
}
using Kinetix;
using UnityEngine;
public class MyIkTestClass : MonoBehaviour
{
[SerializeField] private Animator myAnimator;
private string avatarID;
//This code is from the Quickstart example
private void Awake()
{
KinetixCore.OnInitialized += OnInitialize;
KinetixCore.Initialize(new KinetixCoreConfiguration()
{
GameAPIKey = "yourGameAPIKey",
PlayAutomaticallyAnimationOnAnimators = true,
EnableAnalytics = true
});
}
private void OnInitialize()
{
KinetixCore.OnInitialized -= OnInitialize;
//Register NPC
avatarID = KinetixCore.Animation.RegisterAvatarAnimator(myAnimator);
//Register IK event
KinetixCore.Animation.RegisterIkEventOnAvatar(avatarID, Kinetix_OnLocalPlayer);
}
private void OnDestroy()
{
//"Try" in case the sdk is disposed before us.
//Unregister the event
try
{
KinetixCore.Animation.UnregisterIkEventOnAvatar(avatarID, Kinetix_OnLocalPlayer);
}
finally {}
}
private void Kinetix_OnBeforeIK(IKInfo currentPose)
{
//In this example, every position and locations
//depends on the scene and on the character (= if it has long arms or a big head).
//We can use IK methods here.
//We set the Elbow hint at the left foot position.
KinetixCore.Animation.SetIKHintPositionOnAvatar(avatarID, AvatarIKHint.LeftElbow, Vector3.left);
//Set target position for the left hand
KinetixCore.Animation.SetIKPositionOnAvatar(avatarID, AvatarIKGoal.LeftHand, Vector3.left + 2*Vector3.up);
//Set weight between the Animation pose and the IK pose.
KinetixCore.Animation.SetIKPositionWeightOnAvatar(avatarID, AvatarIKGoal.LeftHand, 1); //1 = full ik
//Make the palm look at the forward (= hand's back look at the back) and make the fingers look up
KinetixCore.Animation.SetIKRotationOnAvatar(avatarID, AvatarIKGoal.LeftHand, Quaternion.LookRotation(Vector3.up, Vector3.back));
//Set weight between the Animation pose and the IK pose.
KinetixCore.Animation.SetIKRotationWeightOnAvatar(avatarID, AvatarIKGoal.LeftHand, 1); //1 = full ik
}
}
Our IK ensure that if you have multiple rigs in your virtual world, the IK rotation will be the same for both characters. The global rotations are described as follow :