# Rig

## Kinemation Rig

The **Scriptable Animation System** introduces a new way of storing the information about the character skeleton hierarchy - Rig Assets.

**Rig Asset** is a Scriptable Object, which contains:

* Character Skeleton hierarchy
* Element Chains
* Animation Curves

To create a new **Rig Asset Right click -> KINEMATION -> Rig:**

<figure><img src="https://784345943-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxcUmJ78NSw1bSUlSO9oP%2Fuploads%2FwRRrDpDNycKAC4afBm9u%2Fimage.png?alt=media&#x26;token=9cc914f7-b18c-486b-87af-c58e1ed4ad02" alt="" width="397"><figcaption><p>Rig Asset.</p></figcaption></figure>

In order to update the character skeleton hierarchy, it's required to provide a **K Rig Component** reference. To do this, attach the **K Rig Component** to the root bone of the skeleton hierarchy:

<figure><img src="https://784345943-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxcUmJ78NSw1bSUlSO9oP%2Fuploads%2F1hoLjw04ENK8zgGzITZE%2Fimage.png?alt=media&#x26;token=bdc33277-457c-464f-bef4-439f22e8787a" alt="" width="257"><figcaption></figcaption></figure>

**Rig Component** will iterate over all child transforms of the root bone and include them in the hierarchy collection. Then, you you will need to specify the **Rig Component** reference in your desired **Rig Asset** and hit the *Import Rig* button/

The **Rig Asset** does not store the Transform references, instead, it has a List of **KRigElements** - a struct which has a name and an **index** of the element in the hierarchy.

Then, you can retrive the Transform reference based on the **KRigElement**:

{% code title="AdditiveLayerState.cs" %}

```csharp
...
_targetBone = RigComponent.GetRigTransform(_settings.targetIkElement);
...
```

{% endcode %}

Thanks to this system we can select bones we want to modify in the data assets without holding a reference to the bone!

## Practical Example

The Rig Asset has another cool feature - automated bone selection. If you want to select a bone from the pop-up window in your custom script, make sure to implement the **IRigUser** interface:

{% code title="YourCustomScript.cs" %}

```csharp
...

[SerializeField] private rigAsset;

// Make sure to return the desired KRig asset here.
public KRig GetRigAsset()
{
    return rigAsset;
}
...
```

{% endcode %}

The only method this interface provides is GetRigAsset - it will be used by a custom drawer to select a rig element.

Now, simply add a KRigElement to your script:

{% code title="YourCustomScript.cs" %}

```csharp
...

[SerializeField] private rigAsset;
[SerializeField] private KRigElement yourCustomElement;

// Make sure to return the desired KRig asset here.
public KRig GetRigAsset()
{
    return rigAsset;
}
...
```

{% endcode %}

Now when you get back to the Editor, you will be able to select an element from the hierarchy. This concept is used for **Animator Layer Settings** and other entities in the framework.&#x20;

And in the next section we will learn about the new layer system!

## KRigElement

This struct represents the element in the hierarchy:

```csharp
public struct KRigElement
{
    // Element name.
    public string name;
    // Index in the hierarchy.
    [HideInInspector] public int index;
    // Whether the element is an IK-object.
    public bool isVirtual;
}
```

**Rig Elements** are visually represented as selectable widgets in Rig Asset, Animator Layers and other scripts:

<figure><img src="https://784345943-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxcUmJ78NSw1bSUlSO9oP%2Fuploads%2FS65NSdOvX72s23sYOBxo%2Fimage.png?alt=media&#x26;token=7f17d812-4cd3-44a8-bdd8-cca772948ce2" alt="" width="338"><figcaption><p>Rig elements.</p></figcaption></figure>

The **Rig Element** does not represent the Transform itself, so you need to re-trieve the Transform reference via the **Rig Component**:

```csharp
Transform yourTransform = RigComponent.GetRigTransform(yourRigElement);
```

When you select an element in the editor, the system caches the index in the hierearchy automatically. However, it is also possible to get a Transform reference by a string name only:

```csharp
Transform yourTransform = RigComponent.GetRigTransform("yourRigElementName");
```

{% hint style="success" %}
**Tip:** Transforms re-trieved via the Rig Component are always valid, unless the index is inentionally changed in the constructor. If the Rig Element is empty, the Rig Component will return a reference to the root bone.
{% endhint %}

## KPose

**KPose** is a struct that represents an element pose in the **Kinemation Rig**. Let's see what fields it has:

```csharp
// The space we are going to apply the pose in.
public enum ESpaceType
{
    BoneSpace, // Current frame space.
    ParentBoneSpace, // The space of the parent bone.
    ComponentSpace, // The space of the root bone.
    WorldSpace // World space.
}

// Whether the operation is additive or absolute.
public enum EModifyMode
{
    Add,
    Replace
}

public struct KPose
{
    public KRigElement element; // The target element.
    public KTransform pose; // The desired pose.
    public ESpaceType space; // The space we are going to operate in.
    public EModifyMode modifyMode; // Whether additive or replace.
}
```

The KPose has many applications, like pose caching, blending and a convenient pose offset. For example, it is very convenient for bone modifications:

{% code title="KAnimationMath.cs" overflow="wrap" %}

```csharp
public static void ModifyTransform(Transform component, Transform target, in KPose pose, float alpha = 1f)
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kinemation.gitbook.io/scriptable-animation-system/fundamentals/rig.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
