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