> For the complete documentation index, see [llms.txt](https://malbersanimations.gitbook.io/animal-controller/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://malbersanimations.gitbook.io/animal-controller/secondary-components/ik-manager.md).

# IK Manager

## Overview

The **IK Manager** owns every runtime bone correction on a character: hands locked onto a rifle, feet planted on a slope, the head following the aim direction, a hand grabbing a ledge.

Everything is built from three pieces:

* **IK Set** — one mechanic (*Aim Bow*, *Carry Box*, *Climb*…). This is what you turn on and off.
* **IK Processor** — a solver inside a Set. It moves one bone or one limb.
* **Weight Processor** — a gate on the Set's weight. It decides *when* the Set is allowed to work.

Add it to the character root: `Malbers ▸ IK ▸ IK Manager`. One per character — the component is `[DisallowMultipleComponent]`.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2Ftwyl6Bd4ldHJmuX5KFFG%2Fimage.png?alt=media&#x26;token=51527369-e42e-4755-b393-dc7a0177c221" alt="" width="548"><figcaption></figcaption></figure>

***

## Requirements

* **Animator** — on the character or one of its children. `Reset` finds it. Without one the component logs an error and disables itself.
* **A Transform for every target** a processor needs. A processor whose target is missing is skipped, never forced.
* **Aim component** — only when the Set contains a Look-At or aim-driven processor. It supplies the direction. `OnValidate` assigns it automatically if the character has one.
* **Animal Controller** (`MAnimal`) — only for the *State*, *Mode* and *Stance* weight processors. Everything else works on a bare Animator.

{% hint style="info" %}
The component runs at `DefaultExecutionOrder(1500)`, so it always applies its corrections **after** the Animal Controller has finished moving the character for that frame.
{% endhint %}

***

## How it works

Say you need to fix the hands and spine while carrying a box, hold a rifle with both hands, or place a hand properly when climbing a wall. In every case the recipe is the same:

1. Create an **IK Set** and name it.
2. Add the **IK Processors** that correct the bones involved.
3. Add **Weight Processors** so the Set only works while the character is in the right State, Stance, Mode or animation.
4. Enable the Set — from a Reaction, an Animator state, an item, or code.

Each frame the Manager walks its Sets twice:

| Pass                  | When                | Who runs                                                                                                 |
| --------------------- | ------------------- | -------------------------------------------------------------------------------------------------------- |
| `OnAnimatorIK(layer)` | Unity's IK pass     | **Humanoid** processors — they talk to the Avatar (`SetIKPosition`, `SetLookAt`, `SetBoneLocalRotation`) |
| `LateUpdate`          | after all animation | **Generic** processors — they write bone rotations directly, so they work on any skeleton                |

When the Animator's Update Mode is **Animate Physics**, the `LateUpdate` pass is moved to a `WaitForFixedUpdate` coroutine instead, so IK stays in sync with physics.

{% embed url="<https://streamable.com/p8rire>" %}

***

## The weight pipeline

Every Set resolves to a single **Final Weight** each frame, and every processor multiplies its own weight on top of it:

```
  IK Set Weight  ×  Global Weight
      ×  Weight Processor 1
      ×  Weight Processor 2  …            →   Final Weight   (smoothed by Lerp Weight)
                                                  ×  IK Processor Weight
                                                  ×  Anim Parameter (float curve)
                                                  =  what the solver actually applies
```

The chain short-circuits: as soon as the running weight drops to \~0 the remaining Weight Processors and all the solvers are skipped, so a disabled Set costs almost nothing.

{% hint style="success" %}
In Play Mode the Set shows a read-only **Final Weight** field at the top of its inspector. If a Set is not doing anything, look there first — a Weight Processor is usually holding it at zero.
{% endhint %}

***

## Properties

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FHq8NUvIutkZPHVSeThgC%2Fimage.png?alt=media&#x26;token=62eaf954-bb90-46bc-9c9a-60597c61f5d7" alt="" width="539"><figcaption></figcaption></figure>

### Animator

Reference to the character's Animator. **\[Required]**

### Weight

Global weight for **all** IK Sets. Set it to `0` to switch the whole IK system off in one place — useful for cutscenes, ragdolls, or a quality setting.

***

## Global Targets

A list of **IK Tag → Transform** pairs shared by every Set on this character. Processors reference a `Tag`, and the Manager resolves it here.

This is what makes an IK Set portable. A processor that says *"aim the bone tagged **IK\_Head**"* works on any character, because the Tag is resolved per character instead of pointing at one specific Transform.

| Button            | What it does                                                                                                                                                                                                           |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Get Targets**   | Shown while the list is empty. Collects every unique Transform used by the Sets' `Targets` arrays and adds them, guessing a Tag from the bone name (head, neck, chest, hip, left/right hand, left/right foot, goals…). |
| **Clear Targets** | Empties the list. Asks for confirmation.                                                                                                                                                                               |

`OnValidate` also fills empty entries whose Tag name contains *head*, *neck*, *chest*, *upperchest* or *root* by searching the skeleton.

### The IK Tag asset

`IK Tag` is a standard Malbers ID asset — a name plus a hash. Create one with `Assets ▸ Create ▸ Malbers Animations ▸ IK Tag`.

{% hint style="info" %}
Prefer **Tags** over **Target Index** everywhere. The index points into that one Set's `Targets` array, which only exists in the scene; a Tag is resolved from the Global Targets of whatever character the Set ends up on — and it is the only option that survives being stored in an **IK Set Library** or an **IK Profile**.
{% endhint %}

***

## IK Set Library

Bone orientations differ from rig to rig, so a finished IK setup is usually authored once per rig and reused across every character that shares it.

An **IK Set Library** is an asset holding a whole collection of IK Sets. Create one with `Assets ▸ Create ▸ Malbers Animations ▸ IK ▸ IK Set Library`, or press **Save** on the Manager.

#### Library

The asset applied to this Manager. Its Sets are always **deep copied**; the asset itself is never modified at runtime.

#### Mode

| Value        | Result                                                     |
| ------------ | ---------------------------------------------------------- |
| **Override** | The Library replaces every Set on the Manager.             |
| **Additive** | The Library's Sets are appended to the Sets already there. |

#### Load on Awake

Apply the Library automatically on `Awake`, before any Set is initialized. Disable it if you prefer to bake the Sets in the Editor with the **Load** button, or to load a Library yourself at runtime.

#### Load / Save

**Load** copies the Library's Sets into the Manager right now, so you can see and tweak them before playing. **Save** writes the Manager's Sets back into the Library (or creates a new asset if none is assigned). Each Set also has its own **Save** button to store just that one.

{% hint style="warning" %}
Sets stored in a Library must resolve their targets through **IK Tags**. Scene Transform references cannot be serialized inside an asset, so the `Targets` array is hidden when a Set lives in a Library.
{% endhint %}

Swapping a Library while the game runs is supported: the old Sets are disabled and the new ones initialized and enabled.

***

## IK Sets

Each IK Set is one IK configuration for one mechanic on your controller — one for carrying a box, another for two-handed weapons, another for aiming a bow.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2F1nLDojMFbMrxziValLLB%2Fimage.png?alt=media&#x26;token=dbe6a288-b41b-4a70-b89c-5df12adb2a11" alt="" width="541"><figcaption></figcaption></figure>

The list shows, per Set: the **Active** toggle, the **Name**, and the current **Weight**. Select a row to edit it below; the selected Set is the one drawn with gizmos in the Scene View.

#### Active

Enables or disables the Set **instantly**, with no smoothing. This is the raw switch — `Enable()` from code uses the smooth path instead.

#### IK Set Name

Used to find the Set from an IK Reaction, an IK Behavior, an IK Connector or code. Duplicated names log a warning: `FindSet()` only ever returns the first match.

#### Weight

Local weight of this Set, the first term of the weight pipeline.

The rest of the Set is split across three tabs.

### IK Set tab

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FPJCLmdCvGFOXYSVqBoIG%2Fimage.png?alt=media&#x26;token=d4ab4a86-ae8d-41b5-a41c-d312e646099f" alt="" width="550"><figcaption></figcaption></figure>

#### Enable Time

Seconds taken to fade the Set in when it is enabled. `0` is instant. The small curve next to it (**Enter Lerp**) shapes the fade.

#### Disable Time

Seconds taken to fade the Set out. The **Exit Lerp** curve shapes it.

#### Aimer

The `Aim` component that supplies a direction to Look-At and aim-driven processors. Auto-assigned on validate when the character has one.

#### Targets

Scene Transforms handed to processors that use a **Target Index**. Mostly filled at runtime by the **IK Connector** or by `Target_Set()`.

#### Clear Targets On Disable

Empties the `Targets` array when the Set finishes fading out, so a stale grab point can't be reused by mistake.

### Weight Processors tab

Modular gates on the Set's weight — drive it from an animation curve, restrict it to a look angle, or kill it while the character is swimming.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FgsAll9ddLK62FyI9sBt3%2Fimage.png?alt=media&#x26;token=55116bfb-8d38-49be-bf58-eb4d687f8b66" alt="" width="533"><figcaption></figcaption></figure>

#### Lerp Weight

How fast the Final Weight chases its target value. `0` applies it instantly.

### Events tab

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FRz9vBRpnhSHxkNfKcfd2%2Fimage.png?alt=media&#x26;token=3d593ef0-f617-45a4-8dc7-19c77798cd79" alt="" width="535"><figcaption></figcaption></figure>

#### On Weight Changed `(float)`

Invoked every time the Final Weight changes.

#### On Set Enable

Invoked when the Set starts fading in.

#### On Set Disable

Invoked when the Set has finished fading out.

***

## IK Processors

The solvers. Everything that actually moves a bone lives here.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2F1vmzNAz3Z6kYSgxOhpqH%2Fimage.png?alt=media&#x26;token=3fd104ee-1254-4160-84e5-d920863af705" alt="" width="540"><figcaption></figcaption></figure>

Each row is one processor: an **Active** toggle, its **Name**, its **Tag** (only when the processor needs a target), its **Weight**, and a **D** button that duplicates it. Select a row to open its settings underneath.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FyI8XZnhezsntwrTXGQ0g%2Fimage.png?alt=media&#x26;token=57d58a46-9d63-4dbf-aa8f-5aa15db65ea7" alt="" width="543"><figcaption></figcaption></figure>

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2FrW6NqiVp5ICTKJayYiHV%2Fimage.png?alt=media&#x26;token=638c72ea-232f-4b1c-80cb-462142cf7764" alt="" width="539"><figcaption></figcaption></figure>

### Verify

The green **Verify** button in the processor list header asks every processor in the Set to check itself: missing bones, missing Tags, Target Indexes pointing outside the array, Aimers that were never assigned. The result is printed to the Console, one line per processor.

<figure><img src="https://963537199-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lzhr1XSMzMqNXjRnNlb%2Fuploads%2Fdof6D4lNE0Yv0B84TJ3q%2Fimage.png?alt=media&#x26;token=129158b4-d59b-489c-9bfe-e0b2f3e9e69b" alt=""><figcaption></figcaption></figure>

### Copy / Paste

**Copy** on a Set puts its IK Processors and Weight Processors on a clipboard; **Paste** appears on any other Set — including Sets living inside an **IK Set Library** or an **IK Profile** asset. Tags are preserved, so a Set copied between two characters with the same tagging keeps working.

***

## Turning Sets on and off

An IK Set does nothing until something enables it. There are four ways, and they all end up calling the same API.

### IK Reaction

A `Reaction` — usable anywhere Reactions are (Modes, States, Interactions, Item Actions, events). Menu path `Malbers ▸ IK`.

* **Action** — `Activate` or `Deactivate` the Set named in **IK Set**.
* **Target Action** — `Set Targets` or `Clear Targets`, using the **IK Tag → Transform** pairs listed on the reaction. This is how a ladder hands its rungs to the character, or a weapon hands over its grip point.

### IK Behavior

A `StateMachineBehaviour`. Drop it on an Animator state to toggle a Set from the animation itself.

* **On Enter** — enable/disable when the state begins.
* **On Exit** — enable/disable when the state ends.
* **On Time** — toggle inside a normalized time range, then restore the previous value. Fires once per loop.

### IK Connector

A component on the **other** object — the ladder, the box, the vehicle. It finds the character's IK source and pushes both the Set name and the target Transforms into it.

* **IK Set** — name of the Set. Use commas for several: `Aim,Grip`.
* **Targets** — the Transforms that Set needs.
* **Set Target On Source / On Enable** — when to hand the targets over.

### Animation curve

Give a processor an **Anim Parameter** (a float Animator parameter driven by a curve inside the clip). The processor's weight is multiplied by it, so the IK fades exactly with the animation. See *Animator Parameter (Float)* on the Weight Processors page to do the same for a whole Set.

***

## Debug

* Select the IK Manager and expand it: the **selected Set** draws the gizmos of its **selected processor** in the Scene View, plus the gizmos of all its Weight Processors.
* Many processors expose their own **Gizmos** toggle and draw handles you can drag in Play Mode to author offsets live.
* **Final Weight** (Play Mode, top of the Set) tells you whether the problem is the weight chain or the solver.
* **Verify** catches missing references before you press Play.

***

## API

```csharp
var ik = character.GetComponent<IKManager>();

ik.Set_Enable("Aim Bow");            // smooth enable
ik.Set_Disable("Aim Bow");           // smooth disable
ik.Set_Enable("Aim,Grip", true);     // comma separated
ik.Set_Weight("Aim Bow", true);      // hard 0/1, no smoothing

ik.Target_Set("Climb", handHold, 0); // one target by index
ik.Target_Set("Climb", transforms);  // replace the whole array
ik.Target_Clear("Climb");            // clear them all

ik.Target_Add_Global(pair);          // add/replace a Tag → Transform
ik.Target_Remove_Global(pair);

ik.Processor_SetEnable("Aim Bow", "Head LookAt", false);

ik.Library_Load(library);            // uses the serialized Mode
ik.Library_Override(library);
ik.Library_Add(library);

IKSet set = ik.FindSet("Aim Bow");
set.FinalWeight;                     // read-only, current resolved weight
```

The Manager implements `IIKSource`, so anything holding that interface can drive it without knowing about the concrete component.
