Skip to content
IK Anchor

IK Anchor

It takes about 10 minutes to read this article

This article outlines the definition of IK, what functions IK Anchors have, how they perform and how they are used.

What is IK?

Function Description: Inverse Kinematics (IK) is a technique that uses skeleton systems in computer animation to simulate the actions of objects. This technique allows parts of an object (e.g. arms, legs, etc.) to be automatically modified as the root moves, achieving more natural and realistic animation. We provide [Auto IK] function for character feet to adapt to various ground effects. include uneven ground, stairs, etc.

image-20240828174057168

In addition to the [Automatic IK] function, we also provide a logical object for [IK Anchor], which allows the user to control the character's hand position or foot position when using interactive objects involving the hand or foot to prevent die-piercing. As an example description, a more typical hand interaction object is a weapon (bow/Hot Weapon, etc.) and a foot interaction object is a vehicle ride (bike/horse, etc.)

Enable Automatic IK

Function description: Character foot position will ray down to detect ground distance and enable IK effect, try to keep character foot close to the ground, reduce the phenomenon of character standing on irregular ground during the experience, improve experience.

Related API:

ts
// The current client Player character enables automatic IK
IKAnchor.autoEnableIK(Player.localPlayer.character, true);
// Current client Player character turns off automatic IK
IKAnchor.autoEnableIK(Player.localPlayer.character, false);
// The current client Player character enables automatic IK
IKAnchor.autoEnableIK(Player.localPlayer.character, true);
// Current client Player character turns off automatic IK
IKAnchor.autoEnableIK(Player.localPlayer.character, false);

Use of IK Anchors

1. How do I find IK Anchor?

Find the object of IK Anchor in the Asset Library-Gameplay Object list.

image-20240828174252118

2. Use IK Anchor

Taking a motorcycle that the character can drive as an example, if we do not use IK Anchor, the effect is as follows:

Once we first find the IK Anchor object, we can manually drag it under the motorcycle object (or under an Interactor object), and then we can adjust the hand position and foot position by modifying the IK Anchor's properties.

image-20240828175418184

First we have to modify the world coordinates of the IK anchors to fit as closely as we want the character's hands or feet to the position they want to be placed. For example, if we want the character's hands on the handlebars of a motorcycle, the IK Anchor position needs to be set to the handlebar position of the motorcycle.

Next we need to modify the corresponding IK Anchor to their IK type and the IK type to the character skeleton we want to apply, say the IK Anchor of the left handlebar of the motorcycle, we need to modify the IK Anchor to the left hand. By analogy, the IK type of the IK Anchor at the right handle of the motorcycle should be modified to the right hand, the IK type of the IK Anchor at the left pedal of the motorcycle to the left foot, and the IK type of the IK Anchor at the right pedal of the motorcycle to the right foot. At the same time we can change the name for easy identification.

Then we need to write code that enables character IK when the character triggers a ride and applies it to the character being ridden.

ts
@Component
export default class NewScript extends Script {
    // Declare the IK type
    leftHandIk:IKAnchor;
    rightHandIk:IKAnchor;
    leftFootIk:IKAnchor;
    rightFootIk:IKAnchor;
    /** This function is called before the first frame update when the script is instanced */
    protected onStart(): void {
        // Find the left hand IK Anchor via GUID
        this.leftHandIk = GameObject.findGameObjectById("0EC27D11") as IKAnchor;
        // Find the right hand IK Anchor via GUID
        this.rightHandIk = GameObject.findGameObjectById("22DBBDD4") as IKAnchor;
        // Find the IK Anchor of your left foot via GUID
        this.leftFootIk = GameObject.findGameObjectById("00BD0000") as IKAnchor;
        // Find the IK Anchor of the right foot via GUID
        this.rightFootIk = GameObject.findGameObjectById("0364CBB7") as IKAnchor;
        // Execute the following logic when pressing the W key (for a description here, the logic of the IK application object should be placed on the logic triggered by the drive button or on the logic to perform the riding action. Since the script of the motorcycle example is too long and not easy to learn, it is simplified to a key simulation)
        InputUtil.onKeyDown(Keys.W,()=>{
            // left hand IK Anchor applied to current character
            this.leftHandIk.active(Player.localPlayer.character);
            // Right hand IK Anchor applied to current character
            this.rightHandIk.active(Player.localPlayer.character);
            // IK Anchor of left foot applied to current character
            this.leftFootIk.active(Player.localPlayer.character);
            // The IK Anchor on the right foot is applied to the current character
            this.rightFootIk.active(Player.localPlayer.character);
        }) 
    }
}
@Component
export default class NewScript extends Script {
    // Declare the IK type
    leftHandIk:IKAnchor;
    rightHandIk:IKAnchor;
    leftFootIk:IKAnchor;
    rightFootIk:IKAnchor;
    /** This function is called before the first frame update when the script is instanced */
    protected onStart(): void {
        // Find the left hand IK Anchor via GUID
        this.leftHandIk = GameObject.findGameObjectById("0EC27D11") as IKAnchor;
        // Find the right hand IK Anchor via GUID
        this.rightHandIk = GameObject.findGameObjectById("22DBBDD4") as IKAnchor;
        // Find the IK Anchor of your left foot via GUID
        this.leftFootIk = GameObject.findGameObjectById("00BD0000") as IKAnchor;
        // Find the IK Anchor of the right foot via GUID
        this.rightFootIk = GameObject.findGameObjectById("0364CBB7") as IKAnchor;
        // Execute the following logic when pressing the W key (for a description here, the logic of the IK application object should be placed on the logic triggered by the drive button or on the logic to perform the riding action. Since the script of the motorcycle example is too long and not easy to learn, it is simplified to a key simulation)
        InputUtil.onKeyDown(Keys.W,()=>{
            // left hand IK Anchor applied to current character
            this.leftHandIk.active(Player.localPlayer.character);
            // Right hand IK Anchor applied to current character
            this.rightHandIk.active(Player.localPlayer.character);
            // IK Anchor of left foot applied to current character
            this.leftFootIk.active(Player.localPlayer.character);
            // The IK Anchor on the right foot is applied to the current character
            this.rightFootIk.active(Player.localPlayer.character);
        }) 
    }
}

After triggering our character IK function by pressing a button, we run the project again and will see the character placing hand and foot positions according to our IK Anchor.

After we triggered the script, the hands and feet were in a significantly better position, but the knees were still molded, and we needed to modify the knee axis.

image-20240828175515977

We find the IK Anchor object with the closest knee position. Here we find the IK Anchor of the left foot and click Modify its [Joint Orientation] property to re-modify to 0,-90,0. it is possible to rotate that knee part of the joint 90 degrees outward. In the end, we get what we want:

3. Close IK Anchor

Above we describe how to use the IK Anchor function, but if we enable IK Anchor, characters will move according to IK Anchor whether they play animations or do other things. For example description, for example, we have got out of the car, there is essentially no need to turn off the hand IK and foot IK function, at this point, you need to turn off the IK function to prevent other interactive functions such as the movement of our characters. So we need to add the code to the get off script to close IK Anchor as follows

ts
// Execute the following logic when pressing Q (use the key to simulate getting off condition)
InputUtil.onKeyDown(Keys.Q,()=>{
    // Turn off the IK function on the left hand
    this.leftHandIk.deactivate();
    // Turn off the right hand IK function  
    this.rightHandIk.deactivate();
    // Turn off IK function for left foot
    this.leftFootIk.deactivate();
    // Turn off the IK function on the right foot
    this.rightFootIk.deactivate();
})
// Execute the following logic when pressing Q (use the key to simulate getting off condition)
InputUtil.onKeyDown(Keys.Q,()=>{
    // Turn off the IK function on the left hand
    this.leftHandIk.deactivate();
    // Turn off the right hand IK function  
    this.rightHandIk.deactivate();
    // Turn off IK function for left foot
    this.leftFootIk.deactivate();
    // Turn off the IK function on the right foot
    this.rightFootIk.deactivate();
})

4. Dynamically generate IK anchors

image-20240828175548288

We can view the GUID of the asset by hovering the mouse over the logical object, or by right-clicking and copying the GUID of the object. Then dynamically create the corresponding assets via GUID.

Sample script to dynamically generate IK anchors:

ts
// asynchronous spawn, downloaded when no assets are found and generated
GameObject.asyncSpawn("12683").then((obj) => {
    let IKObject = obj as IKAnchor;
})
// asynchronous spawn, downloaded when no assets are found and generated
GameObject.asyncSpawn("12683").then((obj) => {
    let IKObject = obj as IKAnchor;
})
ts
// normal spawn generated, cannot generate without priority loading or preloaded assets
let IKObject = GameObject.spawn("IKAnchor") as IKAnchor;
// normal spawn generated, cannot generate without priority loading or preloaded assets
let IKObject = GameObject.spawn("IKAnchor") as IKAnchor;

Introduction to IK Anchor Properties

1. Type of IK

Function Description: The IK type mainly determines the skeleton position of the IK anchor affecting character. Currently we provide only 4 skeleton positions, which are left hand, right hand, left foot, right foot.

2. Joint orientation

Function Description: Modifying joint orientation will affect the orientation of the skeleton space associated with the IK type. For example, the connected skeleton of the hand IK is the joint of the elbow and the connected skeleton of the foot IK is the knee joint. Joint orientation will directly affect the orientation of the elbow and knee joints.

Presentation effects:

Related API:

ts
// Find the corresponding IK Anchor object via GUID
let IK = GameObject.findGameObjectById("3BAABEBE") as IKAnchor;
// Apply IK to the current character
IK.active(Player.localPlayer.character); 
// Set the joint anchor of IK to (90,0,0)
IK.jointTarget = new Vector(90,0,0)
// Find the corresponding IK Anchor object via GUID
let IK = GameObject.findGameObjectById("3BAABEBE") as IKAnchor;
// Apply IK to the current character
IK.active(Player.localPlayer.character); 
// Set the joint anchor of IK to (90,0,0)
IK.jointTarget = new Vector(90,0,0)

3. Weight

Function description: When IK anchor function is activated, the mixed weight of character animation and IK effect, the value range is 0-1, the value is 0, then all based on character animation effect, the value is 1, then all based on character IK effect.

Related API:

ts
// Set the IK weight to 1
IK.weight = 1
// Set the IK weight to 1
IK.weight = 1

4. Time of Blend In

Feature Description: Time it takes to mix current animation to IK effect after IK anchor is activated

Related API:

ts
// Mix IK with time = 10
IK.blendInTime = 10;
// Mix IK with time = 10
IK.blendInTime = 10;

5. Time of Blend Out

Feature Description: Time required to redo from IK Mix Effect to normal character animation after disabling IK Anchor

Related API:

ts
// Mix IK out time = 10
IK.blendOutTime = 10;
// Mix IK out time = 10
IK.blendOutTime = 10;