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.
usingKinetix;usingUnityEngine;publicclassMyIkTestClass:MonoBehaviour{ [SerializeField] privateAnimator myAnimator; //This code is from the Quickstart exampleprivatevoidAwake() {KinetixCore.OnInitialized+= OnInitialize;KinetixCore.Initialize(newKinetixCoreConfiguration() { GameAPIKey ="yourGameAPIKey", PlayAutomaticallyAnimationOnAnimators =true, EnableAnalytics =true }); }privatevoidOnInitialize() {KinetixCore.OnInitialized-= OnInitialize; //Register local PlayerKinetixCore.Animation.RegisterLocalPlayerAnimator(myAnimator); //Register IK eventKinetixCore.Animation.RegisterIkEventOnLocalPlayer(Kinetix_OnBeforeIK); }privatevoidOnDestroy() { //"Try" in case the sdk is disposed before us. //Unregister the eventtry {KinetixCore.Animation.UnregisterIkEventOnLocalPlayer(Kinetix_OnBeforeIK); }finally {} }privatevoidKinetix_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 handKinetixCore.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 }}
usingKinetix;usingUnityEngine;publicclassMyIkTestClass:MonoBehaviour{ [SerializeField] privateAnimator myAnimator;privatestring avatarID; //This code is from the Quickstart exampleprivatevoidAwake() {KinetixCore.OnInitialized+= OnInitialize;KinetixCore.Initialize(newKinetixCoreConfiguration() { GameAPIKey ="yourGameAPIKey", PlayAutomaticallyAnimationOnAnimators =true, EnableAnalytics =true }); }privatevoidOnInitialize() {KinetixCore.OnInitialized-= OnInitialize; //Register NPC avatarID =KinetixCore.Animation.RegisterAvatarAnimator(myAnimator); //Register IK eventKinetixCore.Animation.RegisterIkEventOnAvatar(avatarID, Kinetix_OnLocalPlayer); }privatevoidOnDestroy() { //"Try" in case the sdk is disposed before us. //Unregister the eventtry {KinetixCore.Animation.UnregisterIkEventOnAvatar(avatarID, Kinetix_OnLocalPlayer); }finally {} }privatevoidKinetix_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 handKinetixCore.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 }}
Target Position
//==============================//// Set value ////==============================////PositionvoidSetIKPositionOnLocalPlayer(AvatarIKGoal _Goal,Vector3 _Value)//Position + Weightvoid SetIKPositionAndWeightOnLocalPlayer(AvatarIKGoal _Goal,Vector3 _Position,float _Weight)//Weightvoid SetIKPositionWeightOnLocalPlayer(AvatarIKGoal _Goal,float _Value)//==============================//// Get value ////==============================////PositionVector3 GetIKPositionOnLocalPlayer(AvatarIKGoal _Goal)//Weightfloat GetIKPositionWeightOnLocalPlayer(AvatarIKGoal _Goal)
Position weight showcase :
//==============================//// Set value ////==============================////PositionvoidSetIKPositionOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,Vector3 _Value)//Position + Weightvoid SetIKPositionAndWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,Vector3 _Position,float _Weight)//Weightvoid SetIKPositionWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,float _Value)//==============================//// Get value ////==============================////PositionVector3 GetIKPositionOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal)//Weightfloat GetIKPositionWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal)
Position weight showcase :
Hint Position
These are positions like "left knee" or "right elbow" used by the IK to orient the elbow or knee in the correct direction.
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 :
//==============================//// Set value ////==============================////RotationvoidSetIKRotationOnLocalPlayer(AvatarIKGoal _Goal,Quaternion _Value)//Rotation + Weightvoid SetIKRotationAndWeightOnLocalPlayer(AvatarIKGoal _Goal,Quaternion _Rotation,float _Weight)//Weightvoid SetIKRotationWeightOnLocalPlayer(AvatarIKGoal _Goal,float _Value)//==============================//// Get value ////==============================////RotationQuaternion GetIKRotationOnLocalPlayer(AvatarIKGoal _Goal)//Weightfloat GetIKRotationWeightOnLocalPlayer(AvatarIKGoal _Goal)
Rotation (and position) weight showcase :
//==============================//// Set value ////==============================////RotationvoidSetIKRotationOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,Quaternion _Value)//Rotation + Weightvoid SetIKRotationAndWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,Quaternion _Rotation,float _Weight)//Weightvoid SetIKRotationWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,float _Value)//==============================//// Get value ////==============================////RotationQuaternion GetIKRotationOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal)//Weightfloat GetIKRotationWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal)
Rotation (and position) weight showcase :
IK Weight
//==============================//// Set value ////==============================//voidSetIKPositionWeightOnLocalPlayer(AvatarIKGoal _Goal,float _Value)void SetIKRotationWeightOnLocalPlayer(AvatarIKGoal _Goal,float _Value)//==============================//// Get value ////==============================//float GetIKPositionWeightOnLocalPlayer(AvatarIKGoal _Goal)float GetIKRotationWeightOnLocalPlayer(AvatarIKGoal _Goal)
//==============================//// Set value ////==============================//voidSetIKPositionWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,float _Value)void SetIKRotationWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,float _Value)//==============================//// Get value ////==============================//float GetIKPositionWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal)float GetIKRotationWeightOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal)
Rotation (and position) weight showcase :
Adjust Hips
This feature let you lock hands or foots into place by moving the hips
//==============================//// Set value ////==============================//voidSetIKAdjustHipsOnLocalPlayer(AvatarIKGoal _Goal,bool _Value)//==============================//// Get value ////==============================//bool GetIKAdjustHipsOnLocalPlayer(AvatarIKGoal _Goal)
//==============================//// Set value ////==============================//voidSetIKAdjustHipsOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal,bool _Value)//==============================//// Get value ////==============================//bool GetIKAdjustHipsOnAvatar(string _PlayerUUID,AvatarIKGoal _Goal)