# Person

<Badge tone="type">sealed class</Badge> <Badge>runtime wrapper</Badge>

```csharp
public sealed class Person
```

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

A plain runtime wrapper (**not a MonoBehaviour**) representing one tracked skeleton and its instantiated character model. Each `Person` is created and owned by [`SkeletonConsumer`](/docs/sdk-api/unity-api/classes/skeletonconsumer) — you obtain instances from its `Persons` collection or `TryGetPerson` / `GetPerson`, never by constructing one yourself. The `Person` holds the solved and raw joint positions, per-joint confidence, the character `Model`, and bone/transform caches; its scaling and IK are driven each frame.

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

:::note[Units]
All positions and lengths are Unity world-space **meters** (`Vector3`); rotations are `Quaternion`. Timestamps are seconds since the Unix epoch (UTC); durations are seconds.
:::

## Properties

<div className="apiPropTable">

| Property | Type | Description |
|---|---|---|
| **Identity & state** | | |
| `Id` | `string` | the person's id — matches [`Skeleton.Id`](/docs/sdk-api/unity-api/classes/skeleton) (the per-track / "PersonId") |
| `IsActivePerson` | `bool` | `true` when this is the local/active person (nearest to the camera/headset) |
| `LastUpdate` | `DateTime` | local time of the last skeleton update |
| `IsAPose` | `bool` | `true` while the person is currently in an A-pose |
| `IsAutoScaled` | `bool` | `true` once auto-scaling has been applied to the model |
| **Character & model** | | |
| `Character` | [`AR51Character`](/docs/sdk-api/unity-api/classes/ar51character) | the live character component driven by this person |
| `Model` | `GameObject` | the instantiated character GameObject |
| `CharacterPrefab` | [`AR51Character`](/docs/sdk-api/unity-api/classes/ar51character) | the prefab `Model` was instantiated from |
| `Animator` | `Animator` | the model's `Animator` |
| `TintColor` | `Color` | tint applied to the model |
| `JointColor` | `Color` | color used when drawing this person's joints/gizmo |
| **Visibility** | | |
| `IsModelVisible` | `bool` | whether the character mesh is shown (see `SetModelVisiblity`) |
| `IsModelGameObjectActive` | `bool` | whether `Model` is active in the hierarchy |
| `IsSkeletonVisible` | `bool` | whether the skeleton gizmo is shown (see `SetSkeletonVisible`) |
| **Joint data** | | |
| `Positions` | `Vector3[]` | solved joint positions (meters, world) — indexed by [`Joints`](/docs/sdk-api/unity-api/classes/joints) |
| `RawPositions` | `Vector3[]` | raw incoming joint positions (meters, world) before solve |
| `Confidence` | `float[]` | per-joint confidence, parallel to `Positions` |
| `HeadPosition` | `Vector3` | midpoint of the eyes (meters) |
| `LastSkeleton` | [`Skeleton`](/docs/sdk-api/unity-api/classes/skeleton) | the most recent skeleton payload (get/set) |
| **Timing** | | |
| `CreationTime` | `double` | capture time when first seen (Unix seconds) |
| `TimeSinceCreation` | `double` | seconds since first seen |
| **Bones & rig caches** | | |
| `RootBoneDFS` | `Transform[]` | bones in depth-first order from the root |
| `Bones` | `Transform[]` | mapped rig bones |
| `AnimatedBones` | `Transform[]` | bones driven by the animator |
| `HeadJoint` / `NeckJoint` | `Transform` | head / neck bone transforms |
| `HeadInitRotation` | `Quaternion` | head bone rotation at bind time |
| `NeckInitLocalRotation` | `Quaternion` | neck bone local rotation at bind time |
| `LeftWristJoint` / `RightWristJoint` | `Transform` | wrist bone transforms |
| `LeftWristJointDFS` / `RightWristJointDFS` | `Transform[]` | wrist sub-trees in depth-first order |
| **Visualization & physics** | | |
| `JointGizmos` | `JointGizmo[]` | per-joint gizmo components |
| `C3DPoints` | `C3DPoint[]` | C3D marker points |
| `ParentConstraints` | `ParentConstraint[]` | parent constraints on the rig |
| `Colliders` | `Collider[]` | the model's colliders |
| `IdLabel` | `GameObject` | optional world-space id label (get/set) |
| `AutoScaleModeOverride` | `AutoScaleMode` | per-person auto-scale override |

</div>

## Method summary

| Method | Returns | |
|---|---|---|
| [`GetPosition`](#getposition) | `Vector3` | <Badge tone="accent">instance</Badge> |
| [`GetRawPosition`](#getrawposition) | `Vector3` | <Badge tone="accent">instance</Badge> |
| [`GetAverageConfidence`](#getaverageconfidence) | `float` | <Badge tone="accent">instance</Badge> |
| [`SetModelVisiblity`](#setmodelvisiblity) | `void` | <Badge tone="accent">instance</Badge> |
| [`SetSkeletonVisible`](#setskeletonvisible) | `void` | <Badge tone="accent">instance</Badge> |
| [`SetActive`](#setactive) | `void` | <Badge tone="accent">instance</Badge> |
| [`GetHeadRotation` / `SetHeadRotation`](#head-rotation) | `Quaternion` / `void` | <Badge tone="accent">instance</Badge> |
| [`ApplyAutoScale` / `ResetScale`](#applyautoscale) | `void` | <Badge tone="accent">instance</Badge> · overloads |
| [`Update`](#update) | `void` | <Badge>consumer-driven</Badge> |
| [`SolveIK`](#solveik) | `void` | <Badge>consumer-driven</Badge> |
| [`DrawGizmo`](#drawgizmo) | `void` | <Badge tone="accent">instance</Badge> |
| [`DestroyModels`](#destroymodels) | `void` | <Badge tone="accent">instance</Badge> |

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

:::note[Driven by SkeletonConsumer]
`Update` and `SolveIK` are public for advanced/manual driving, but in normal use you do **not** call them — [`SkeletonConsumer`](/docs/sdk-api/unity-api/classes/skeletonconsumer) feeds new positions and runs the solve for every person each `LateUpdate`. Read `Positions` / `Confidence` / `Model` and toggle visibility instead.
:::

## Method details

### GetPosition

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

```csharp
public Vector3 GetPosition(int jointIndex);
```

The solved world position (meters) of a single joint — equivalent to `Positions[jointIndex]` with bounds safety.

<Params>
<Param name="jointIndex" type="int">a joint index from [`Joints`](/docs/sdk-api/unity-api/classes/joints) (e.g. `Joints.RWrist`)</Param>
</Params>

<Returns type="Vector3">the joint's solved position in Unity world space, meters</Returns>

<Example inferred>

```csharp
var person = SkeletonConsumer.Instance.ActivePerson;
Vector3 rightWrist = person.GetPosition(Joints.RWrist);   // meters, world
```

</Example>

</ApiBody>

### GetRawPosition

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

```csharp
public Vector3 GetRawPosition(int jointIndex);
```

The raw incoming world position (meters) of a joint, before scaling/IK — equivalent to `RawPositions[jointIndex]`.

<Params>
<Param name="jointIndex" type="int">a joint index from [`Joints`](/docs/sdk-api/unity-api/classes/joints)</Param>
</Params>

<Returns type="Vector3">the joint's raw position in Unity world space, meters</Returns>

</ApiBody>

### GetAverageConfidence

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

```csharp
public float GetAverageConfidence();
```

The mean confidence across the joints that have a confident reading — a quick overall tracking-quality signal.

<Returns type="float">average confidence over confident joints, or `-1` when none are confident</Returns>

<Example inferred>

```csharp
foreach (var person in SkeletonConsumer.Instance.Persons)
{
    float quality = person.GetAverageConfidence();
    if (quality >= 0f && quality < 0.3f)
        Debug.Log($"Low tracking quality for {person.Id}: {quality:F2}");
}
```

</Example>

</ApiBody>

### SetModelVisiblity

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

```csharp
public void SetModelVisiblity(bool visible);
```

Show or hide the character mesh. Reflected by `IsModelVisible`. (Note the method's `Visiblity` spelling.)

<Params>
<Param name="visible" type="bool">`true` to render the model, `false` to hide it</Param>
</Params>

</ApiBody>

### SetSkeletonVisible

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

```csharp
public void SetSkeletonVisible(bool visible);
```

Show or hide the skeleton gizmo for this person. Reflected by `IsSkeletonVisible`.

<Params>
<Param name="visible" type="bool">`true` to draw the skeleton gizmo, `false` to hide it</Param>
</Params>

</ApiBody>

### SetActive

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

```csharp
public void SetActive(bool isActive);
```

Activate or deactivate the person's `Model` GameObject as a whole.

<Params>
<Param name="isActive" type="bool">`true` to activate the model, `false` to deactivate it</Param>
</Params>

</ApiBody>

### Head rotation

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

```csharp
public Quaternion GetHeadRotation();
public void       SetHeadRotation(Quaternion rotation);
```

Read or override the head bone rotation — set it to fuse a headset's orientation onto the tracked person.

<Returns type="Quaternion">the current head rotation</Returns>

</ApiBody>

### ApplyAutoScale

<ApiBody kind="method" tags="instance, overloads">

```csharp
public void ApplyAutoScale();
public void ApplyAutoScale(AutoScaleMode mode);
public void ApplyAutoNonUniformScale(Func<int, int, float> getLengthFunc);
public void ResetScale();
```

Rescale the character's bone lengths to match the tracked person. `ApplyAutoScale()` uses the configured mode; pass an [`AutoScaleMode`](/docs/sdk-api/unity-api/skeletons-and-characters#autoscalemode) to override it. `ApplyAutoNonUniformScale` scales per bone pair using the supplied length function. `ResetScale()` restores the unscaled rig. Sets `IsAutoScaled`.

<Params>
<Param name="mode" type="AutoScaleMode">scaling mode to apply (overload)</Param>
<Param name="getLengthFunc" type="Func<int,int,float>">returns target length for a `(fromJoint, toJoint)` pair (meters)</Param>
</Params>

</ApiBody>

### Update

<ApiBody kind="method" tags="consumer-driven">

```csharp
public void Update(Vector3[] positions);
```

Feed a new set of joint positions (meters, world) into the person, refreshing `RawPositions` and `LastUpdate`. **Called by [`SkeletonConsumer`](/docs/sdk-api/unity-api/classes/skeletonconsumer) each frame** — public only for advanced manual driving.

<Params>
<Param name="positions" type="Vector3[]">joint positions indexed by [`Joints`](/docs/sdk-api/unity-api/classes/joints), in meters</Param>
</Params>

</ApiBody>

### SolveIK

<ApiBody kind="method" tags="consumer-driven">

```csharp
public void SolveIK();
```

Run the IK / character solve for this person, driving `Character` toward the current positions and producing `Positions`. **Driven by [`SkeletonConsumer`](/docs/sdk-api/unity-api/classes/skeletonconsumer)** in `LateUpdate`; do not call it yourself in normal use.

</ApiBody>

### DrawGizmo

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

```csharp
public void DrawGizmo(Color color);
```

Draw this person's skeleton gizmo in the given color (debug visualization).

<Params>
<Param name="color" type="Color">gizmo color</Param>
</Params>

</ApiBody>

### DestroyModels

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

```csharp
public void DestroyModels();
```

Destroy the instantiated character model and associated GameObjects for this person. Normally invoked by the consumer when the person is removed.

</ApiBody>

## PersonEventArgs

<Badge tone="type">class</Badge>

```csharp
public class PersonEventArgs
```

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

The payload for the person-lifecycle events raised by [`SkeletonConsumer`](/docs/sdk-api/unity-api/classes/skeletonconsumer) — `OnPersonCreated`, `OnPersonDeleting`, and `OnPersonDeleted`. It carries the affected `Person`.

<div className="apiPropTable">

| Member | Type | Description |
|---|---|---|
| `Person` | `Person` | the person this event concerns |

</div>

```csharp
public PersonEventArgs(Person person);
```

<Example inferred>

```csharp
SkeletonConsumer.Instance.OnPersonCreated += (sender, e) =>
{
    Person p = e.Person;
    Debug.Log($"Character spawned for {p.Id}; head at {p.HeadPosition} (meters)");
};
```

</Example>

## See also

- [`SkeletonConsumer`](/docs/sdk-api/unity-api/classes/skeletonconsumer) — owns and drives every `Person`; source of `PersonEventArgs`
- [`Skeleton`](/docs/sdk-api/unity-api/classes/skeleton) — the per-frame payload behind `LastSkeleton`; shares the `Id`
- [`Joints`](/docs/sdk-api/unity-api/classes/joints) — joint-index map for `Positions` / `Confidence` / `GetPosition`
- [`AR51Character`](/docs/sdk-api/unity-api/classes/ar51character) — the mocap-driven character this person owns
- [Class index](/docs/sdk-api/unity-api/classes) — all Unity SDK types
