Kinetix Documentation
Website
  • 🖐ïļWelcome
  • 🕚About Kinetix
  • 🖌ïļUser-Generated Emote
    • ðŸĪ–Video-to-animation AI
    • ðŸĪļKinetix Emote Standards
    • ðŸĶīRetargeting
    • 🏂Kinanim (Emote streaming)
    • 🖊ïļTry the User-Generated Emote feature
  • INTEGRATION
    • ðŸĪ·SDK or API: what to choose
    • ðŸĪĐKinetix SDK
      • ⚙ïļSDK - Core Package
      • ðŸ§ĐSDK - Sample scene
      • 🧑‍ðŸ’ŧTested & approved Game Engines for the SDK
      • ðŸ’ŧSDK Integration in Unity
        • ⮇ïļSet-up Unity & Import the SDK
          • 🔑Get your Game authentification API Key
          • ⚙ïļSetup your Unity environment
          • 🔧Install the Kinetix SDK in Unity
          • âŒĻïļSDK Initialization - Unity
        • ⚡Quickstart - Unity SDK
        • ðŸĶ‹SDK Core Modules activation - Unity
          • 🔐Account Management in Unity
          • 💃Animation System - Unity
            • ðŸŽĒUnity's Animator System
            • ðŸŽĻCustom Animation System
            • ðŸŒģRoot Motion
              • RootMotion + NavMeshAgent
            • 🎞ïļFrame Controller
            • 💊IK Controller
            • ðŸŦĨAvatar Mask
          • ðŸ“ķNetwork - Unity SDK
            • Photon PUN
            • Photon Fusion
        • 🕚User-Generated Emote integration (Unity)
          • Embedding the PWA in your Unity application
          • Validation / Retake
        • 🚧How to update Kinetix SDK in Unity?
        • 📕SDK API Reference - Unity
          • KinetixCore
          • KinetixCore.Account
          • KinetixCore.Animation
          • KinetixCore.Metadata
          • KinetixCore.Network
          • KinetixCore.UGC
        • 📂Unity SDK Changelog
      • ðŸ•đïļSDK Integration in Unreal Engine
        • ⮇ïļSet-up Unreal Engine & Download the SDK
          • 🔑Get your Game authentification API Key
          • ⚙ïļSet up your Unreal Engine environment
          • 🔧Install the Kinetix SDK in Unreal
          • âŒĻïļUE SDK Core Package Initialization
        • ⚡Quick Start
        • ðŸĶ‹SDK Core Modules activation - Unreal
          • 🔐Account Management - UE
          • 💃Animation System - UE
            • Local player system in Unreal Engine
            • Avatar system in Unreal Engine
            • Without uploading an avatar (deprecated)
              • Animation in a Third Person Template
              • Animation in an existing project
          • ðŸ“ķNetwork - UE SDK
        • 🕚User-Generated Emote integration (UE)
        • 📕SDK API Reference - UE
          • KinetixCore
          • KinetixCore.Account
          • KinetixCore.Animation
          • KinetixCore.Metadata
          • KinetixCore.Network
        • ⮆ïļUpdating from 0.3 to 0.4
        • 📂UE SDK Changelog
    • 😍Kinetix API
      • 🔑Get your Authentification API key
      • 🔌API routes
      • 🊝API Webhooks
      • 🏓Possible Return Codes
  • Management
    • 🚊Developer Portal
      • ðŸ‘―Avatar Upload
      • ðŸ‘ŪUGC Moderation
    • 🖌ïļUGE: Guides & Best Practices
      • 📐User-Generated Emote specifications
      • 👌Video recording best practices
      • ðŸ‘ŧUser-Generate Emote Use Cases
  • SUPPORT
    • 📎Bugs reports & features requests
    • ❓FAQ
      • FAQ: General questions
      • FAQ: Unity SDK
      • FAQ: Unreal Engine SDK
    • ðŸĪ•Troubleshooting
    • 📚Glossary of terms
Powered by GitBook
On this page
  • Introduction
  • IK Event
  • Target Position
  • Hint Position
  • Global Target Rotation
  • IK Weight
  • Adjust Hips

Was this helpful?

Export as PDF
  1. INTEGRATION
  2. Kinetix SDK
  3. SDK Integration in Unity
  4. SDK Core Modules activation - Unity
  5. Animation System - Unity

IK Controller

PreviousFrame ControllerNextAvatar Mask

Last updated 9 months ago

Was this helpful?

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 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.

void RegisterIkEventOnLocalPlayer(
    IKEffect.DelegateBeforeIkEffect _OnBeforeIkEffect
)

void UnregisterIkEventOnLocalPlayer(
    IKEffect.DelegateBeforeIkEffect _OnBeforeIkEffect
)

Example:

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
    }
}
void RegisterIkEventOnAvatar(
    string _PlayerUUID,
    IKEffect.DelegateBeforeIkEffect _OnBeforeIkEffect
)

void UnregisterIkEventOnAvatar(
    string _PlayerUUID,
    IKEffect.DelegateBeforeIkEffect _OnBeforeIkEffect
)

Example:

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
    }
}

Target Position

//==============================//
// Set value                    //
//==============================//

//Position
void SetIKPositionOnLocalPlayer(
    AvatarIKGoal _Goal,
    Vector3 _Value
)

//Position + Weight
void SetIKPositionAndWeightOnLocalPlayer(
    AvatarIKGoal _Goal,
    Vector3 _Position,
    float _Weight
)

//Weight
void SetIKPositionWeightOnLocalPlayer(
    AvatarIKGoal _Goal, 
    float _Value
)

//==============================//
// Get value                    //
//==============================//

//Position
Vector3 GetIKPositionOnLocalPlayer(
    AvatarIKGoal _Goal
)

//Weight
float GetIKPositionWeightOnLocalPlayer(
    AvatarIKGoal _Goal
)

Position weight showcase :

//==============================//
// Set value                    //
//==============================//

//Position
void SetIKPositionOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal,
    Vector3 _Value
)

//Position + Weight
void SetIKPositionAndWeightOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal,
    Vector3 _Position,
    float _Weight
)

//Weight
void SetIKPositionWeightOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal, 
    float _Value
)

//==============================//
// Get value                    //
//==============================//

//Position
Vector3 GetIKPositionOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal
)

//Weight
float 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.

void SetIKHintPositionOnLocalPlayer(
    AvatarIKHint _Hint,
    Vector3 _Value
)

Vector3 GetIKHintPositionOnLocalPlayer(
    AvatarIKHint _Hint
)
void SetIKHintPositionOnAvatar(
    string _PlayerUUID,
    AvatarIKHint _Hint,
    Vector3 _Value
)

Vector3 GetIKHintPositionOnAvatar(
    string _PlayerUUID,
    AvatarIKHint _Hint
)

Global Target Rotation

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                    //
//==============================//

//Rotation
void SetIKRotationOnLocalPlayer(
    AvatarIKGoal _Goal,
    Quaternion _Value
)

//Rotation + Weight
void SetIKRotationAndWeightOnLocalPlayer(
    AvatarIKGoal _Goal,
    Quaternion _Rotation,
    float _Weight
)

//Weight
void SetIKRotationWeightOnLocalPlayer(
    AvatarIKGoal _Goal, 
    float _Value
)

//==============================//
// Get value                    //
//==============================//

//Rotation
Quaternion GetIKRotationOnLocalPlayer(
    AvatarIKGoal _Goal
)

//Weight
float GetIKRotationWeightOnLocalPlayer(
    AvatarIKGoal _Goal
)

Rotation (and position) weight showcase :

//==============================//
// Set value                    //
//==============================//

//Rotation
void SetIKRotationOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal,
    Quaternion _Value
)

//Rotation + Weight
void SetIKRotationAndWeightOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal,
    Quaternion _Rotation,
    float _Weight
)

//Weight
void SetIKRotationWeightOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal, 
    float _Value
)

//==============================//
// Get value                    //
//==============================//

//Rotation
Quaternion GetIKRotationOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal
)

//Weight
float GetIKRotationWeightOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal
)

Rotation (and position) weight showcase :

IK Weight

//==============================//
// Set value                    //
//==============================//

void SetIKPositionWeightOnLocalPlayer(
    AvatarIKGoal _Goal,
    float _Value
)

void SetIKRotationWeightOnLocalPlayer(
    AvatarIKGoal _Goal, 
    float _Value
)

//==============================//
// Get value                    //
//==============================//

float GetIKPositionWeightOnLocalPlayer(
    AvatarIKGoal _Goal
)

float GetIKRotationWeightOnLocalPlayer(
    AvatarIKGoal _Goal
)
//==============================//
// Set value                    //
//==============================//

void SetIKPositionWeightOnAvatar(
    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                    //
//==============================//

void SetIKAdjustHipsOnLocalPlayer(
    AvatarIKGoal _Goal,
    bool _Value
)

//==============================//
// Get value                    //
//==============================//

bool GetIKAdjustHipsOnLocalPlayer(
    AvatarIKGoal _Goal
)
//==============================//
// Set value                    //
//==============================//

void SetIKAdjustHipsOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal,
    bool _Value
)

//==============================//
// Get value                    //
//==============================//

bool GetIKAdjustHipsOnAvatar(
    string _PlayerUUID,
    AvatarIKGoal _Goal
)

ðŸĪĐ
ðŸ’ŧ
ðŸĶ‹
💃
💊
registering your avatar
Circle = Knee hint Square = Elbow hint Arm and Foot icon = Target for each respective member
Position weight
Position weight
Forward toward the toes (blue) Up toward the Knee (green)
Forward toward the fingers (blue) Up toward the hand's back (green)
Rotation and position weight
Rotation and position weight
Rotation and position weight
Rotation and position weight
Adjust hips