# AR51Character

<Badge tone="type">MonoBehaviour · [RequireComponent(Animator)]</Badge> <Badge>Unity component</Badge>

```csharp
[RequireComponent(typeof(Animator))]
public class AR51Character : MonoBehaviour
```

**Namespace:** `AR51.Unity.SDK`

The component you add to a humanoid character prefab to make it drivable by the SDK. It validates the rig, maps Unity `HumanBodyBones` to its [`CharacterBones`](#characterbones) Transform map, exposes the VR device controllers, and is solved toward incoming skeleton data (body / foot / spine / finger IK) every frame. Add your finished prefab to [`SkeletonConsumer.CharacterPrefabs`](/docs/sdk-api/unity-api/classes/skeletonconsumer); the consumer instantiates one model per tracked person and owns the [`Person`](/docs/sdk-api/unity-api/classes/person) that drives it.

:::tip[How-to]
This page is **reference** (facts only). For the step-by-step *connect → drive a character* walkthrough, see the [How-to guide](/docs/sdk-api/unity-api/skeletons-and-characters).
:::

:::note[Units]
Unity positions and lengths are world-space `Vector3` in **meters**; rotations are `Quaternion`; angles in **degrees**.
:::

## Properties

Public, Inspector-assigned unless noted. Assign the bone/controller Transforms on the prefab.

<div className="apiPropTable">

| Property | Type | Default | Description |
|---|---|---|---|
| **Bone mapping** | | | |
| `Bones` | [`CharacterBones`](#characterbones) | — | the rig's bone-Transform map (see [CharacterBones](#characterbones)) |
| `Person` | [`Person`](/docs/sdk-api/unity-api/classes/person) | — | the tracked person currently driving this character (set by the consumer) |
| `World` | `Transform` | — | the space the character is solved in |
| `LeftForearmTwistJoint` | `Transform` | — | optional left wrist-twist bone |
| `RightForearmTwistJoint` | `Transform` | — | optional right wrist-twist bone |
| **Device controllers** | | | |
| `LeftDeviceController` | `Transform` | — | Transform driven by the left VR controller |
| `RightDeviceController` | `Transform` | — | Transform driven by the right VR controller |
| **Auto scale** | | | |
| `CharacterHeight` | `float` | `1.0` | character height in **meters**, used by advanced non-uniform scaling |
| **Foot contact** | | | |
| `LeftFootBounds` | `Transform` | — | left-foot contact-bounds Transform |
| `RightFootBounds` | `Transform` | — | right-foot contact-bounds Transform |
| **Runtime (read-mostly)** | | | |
| `Animator` | `Animator` | — | the required humanoid `Animator` (read-only) |
| `FootContactSticky` | `FootContactSticky` | — | foot-contact stick state (read-only) |
| `MoveLimbs` | `bool` | — | whether limb IK is applied |

</div>

## Method summary

**Instance**

| Method | Returns | |
|---|---|---|
| [`ValidateCharacter`](#validatecharacter) | `bool` | <Badge>Unity component</Badge> |
| [`GetMissingRequiredMappings`](#getmissingrequiredmappings) | `List<string>` | <Badge>Unity component</Badge> |
| [`GetButtonStatus`](#getbuttonstatus) | `ControllerButtonStatus` | <Badge>Unity component</Badge> |
| [`GetAllButtonStatus`](#getbuttonstatus) | `List<Tuple<ControllerButton, ControllerButtonStatus>>` | <Badge>Unity component</Badge> |

**Static**

| Method | Returns | |
|---|---|---|
| [`GetOrderedLimbPairs`](#getorderedlimbpairs) | `(HumanBodyBones, HumanBodyBones)[]` | <Badge>static</Badge> |

→ Full descriptions in [Method details](#method-details) below.

## Method details

### ValidateCharacter

<ApiBody kind="method" tags="Unity component">

```csharp
public bool ValidateCharacter();
```

Checks that the prefab is a valid humanoid with all required bones and bounds assigned. Call it at setup (per prefab) before relying on a character — an invalid rig will not solve correctly.

<Returns type="bool">`true` if the rig is a valid humanoid with the required bones mapped</Returns>

<Example>

```csharp
foreach (var prefab in SkeletonConsumer.Instance.CharacterPrefabs)
    if (!prefab.ValidateCharacter())
        Debug.LogError("Invalid rig: " + string.Join(", ", prefab.GetMissingRequiredMappings()));
```

</Example>

</ApiBody>

### GetMissingRequiredMappings

<ApiBody kind="method" tags="Unity component">

```csharp
public List<string> GetMissingRequiredMappings();
```

Returns the labels of the required bones/bounds that are not assigned. Use it to report exactly what a prefab is missing when [`ValidateCharacter`](#validatecharacter) returns `false`.

<Returns type="List<string>">labels of unassigned required bones/bounds; empty when the rig is complete</Returns>

</ApiBody>

### GetButtonStatus

<ApiBody kind="method" tags="Unity component">

```csharp
public ControllerButtonStatus GetButtonStatus(ControllerButton button, bool isLeft = false);
public List<Tuple<ControllerButton, ControllerButtonStatus>> GetAllButtonStatus(bool isLeft = false);
```

Read the VR controller button state for this character's person. `GetButtonStatus` reads one button; `GetAllButtonStatus` returns every button with its current status. Pass `isLeft = true` for the left controller.

<Params>
<Param name="button" type="ControllerButton">which controller button to query</Param>
<Param name="isLeft" type="bool">`true` for the left controller, `false` (default) for the right</Param>
</Params>

<Returns type="ControllerButtonStatus">the current status of the requested button</Returns>

:::note
`ControllerButton` and `ControllerButtonStatus` are transport enums (`AR51.GRPC.CVS`); they are surfaced here but not detailed as public types.
:::

</ApiBody>

### GetOrderedLimbPairs

<ApiBody kind="method" tags="static">

```csharp
public static (HumanBodyBones left, HumanBodyBones right)[] GetOrderedLimbPairs();
```

The canonical left/right `HumanBodyBones` limb pairs, in solve order — useful when iterating bones symmetrically.

<Returns type="(HumanBodyBones, HumanBodyBones)[]">the ordered left/right limb-bone pairs</Returns>

</ApiBody>

## CharacterBones

<Badge tone="type">[Serializable] class</Badge> <Badge>Unity component</Badge>

```csharp
[Serializable]
public class CharacterBones
```

**Namespace:** `AR51.Unity.SDK`

The Inspector bone-Transform map assigned to [`AR51Character.Bones`](#properties). Each field is a `Transform` on your rig that the solver drives; assign them in the Inspector (or let validation report any that are missing). Bones:

<div className="apiPropTable">

| Bone | Type | Description |
|---|---|---|
| **Core / spine** | | |
| `root` | `Transform` | rig root |
| `Hips` | `Transform` | hips / pelvis |
| `Spine` | `Transform` | spine |
| `Neck` | `Transform` | neck |
| `head` | `Transform` | head |
| **Left arm** | | |
| `LeftShoulder` | `Transform` | left shoulder |
| `LeftElbow` | `Transform` | left elbow |
| `LeftWrist` | `Transform` | left wrist |
| **Right arm** | | |
| `RightShoulder` | `Transform` | right shoulder |
| `RightElbow` | `Transform` | right elbow |
| `RightWrist` | `Transform` | right wrist |
| **Left leg** | | |
| `LeftHip` | `Transform` | left hip |
| `LeftKnee` | `Transform` | left knee |
| `leftFoot` | `Transform` | left foot |
| `LeftToe` | `Transform` | left toe |
| **Right leg** | | |
| `RightHip` | `Transform` | right hip |
| `RightKnee` | `Transform` | right knee |
| `rightFoot` | `Transform` | right foot |
| `RightToe` | `Transform` | right toe |

</div>

## Related types

These types support `AR51Character` but do not have their own page — see the [Skeletons & Characters area page](/docs/sdk-api/unity-api/skeletons-and-characters):

- [`CharacterMapping`](/docs/sdk-api/unity-api/skeletons-and-characters#charactermapping) — Inspector mapping from an entity id / display name to a character prefab.
- [`CharacterMappingHelper`](/docs/sdk-api/unity-api/skeletons-and-characters) — `TryFind` extension that resolves a prefab by mapping name.
- [`AutoScaleMode`](/docs/sdk-api/unity-api/skeletons-and-characters#autoscalemode) — how the character's bone lengths are rescaled to match the tracked person (`Disabled` / `NonUniform` / `Uniform` / `AdvancedNonUniform`).
- [`CharacterValidation`](/docs/sdk-api/unity-api/skeletons-and-characters) — rig-validation helpers (`AR51.Unity.SDK.Utilities`) used by `ValidateCharacter`.

:::note[Internal — not documented]
The IK / character solver behind this component is **proprietary and treated as a black box**: the per-frame body/foot/spine/finger solve, bone-length auto-scaling, and the internal solver types (`IKSolver` and friends) are not part of the documented public surface. You assign the rig and call `ValidateCharacter`; the SDK drives it.
:::

## See also

- [`SkeletonConsumer`](/docs/sdk-api/unity-api/classes/skeletonconsumer) — instantiates and drives one `AR51Character` per tracked person
- [`Person`](/docs/sdk-api/unity-api/classes/person) — the runtime wrapper that owns this character's model and solved joints
- [`Skeleton`](/docs/sdk-api/unity-api/classes/skeleton) — the per-frame mocap payload that drives the character
- [`Joints`](/docs/sdk-api/unity-api/classes/joints) — joint-index map for the incoming position arrays
- [Class index](/docs/sdk-api/unity-api/classes) — all Unity SDK types
- How-to: [connect → drive a character](/docs/sdk-api/unity-api/skeletons-and-characters)
