# Hand data

<Badge tone="type">struct + enums</Badge> <Badge tone="type">static helpers</Badge>

```csharp
namespace AR51.Unity.SDK            // HandJointInfo, HandType, HandJointType, HandJointInfoExtensions, HandJointTypes, HandJointTypeExtensions, JointSequence
namespace AR51.Unity.SDK.Utilities // HandsAdapterExtensions, HandJointTypeMapping, AnimatorHandsExtensions
```

The data model the SDK uses to report tracked hands, plus the helpers that operate on it. An [`IHandsAdapter`](/docs/sdk-api/unity-api/classes/adapters) returns hands as a `HandJointInfo[]`, where each element's array index equals `(int)HandJointType` — index `0` is the wrist, then thumb, index, middle, ring, and little fingers in order. A joint with `Confidence == 0` is considered missing.

:::caution[Units]
Unity positions are in **meters**, world space. AR 51 mocap data is also in meters, so no conversion is needed inside Unity. (Unreal, by contrast, is cm/degrees.)
:::

## HandJointInfo

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

```csharp
public struct HandJointInfo
```

Per-joint pose and confidence sample for a tracked hand — the element type of the arrays returned by [`IHandsAdapter`](/docs/sdk-api/unity-api/classes/adapters). Per the source doc comment, where finger-level confidence is unavailable the overall hand confidence is used, and a `Confidence` of zero means the joint is missing.

### Fields

<div className="apiPropTable">

| Field | Type | Description |
|---|---|---|
| `HandType` | [`HandType`](#handtype) | which hand (left/right) this joint belongs to |
| `JointType` | [`HandJointType`](#handjointtype) | which anatomical joint this sample represents |
| `Confidence` | `float` | tracking confidence. ⚠️ range appears to be 0–1 (`0` = missing), but not explicitly clamped/documented in source |
| `Position` | `Vector3` | joint position. ⚠️ coordinate space (world vs local) not stated in source; appears to be Unity **world** space based on consumer usage. Units are Unity **meters** |
| `Rotation` | `Quaternion` | joint orientation, in the same space as `Position` |

</div>

### Constructors

```csharp
// "missing" joint: Confidence = 0, Position = Vector3.zero, Rotation = Quaternion.identity
HandJointInfo(HandType handType, HandJointType jointType);

// fully specified sample
HandJointInfo(HandType handType, HandJointType jointType,
              float confidence, Vector3 position, Quaternion rotation);
```

<Example inferred>

```csharp
var adapter = HandsAdapterFactory.GetAdapter();
HandJointInfo[] right = adapter.GetRightJointInfos();

foreach (HandJointInfo j in right)
{
    if (j.Confidence == 0f) continue;            // missing joint
    Debug.Log($"{j.JointType} @ {j.Position} (m)"); // Unity world meters
}
```

</Example>

## HandType

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

```csharp
public enum HandType
```

Identifies a hand.

| Value | Int | |
|---|---|---|
| `RightHand` | `0` | the right hand |
| `LeftHand` | `1` | the left hand |

## HandJointType

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

```csharp
public enum HandJointType
```

Enumerates the hand joints the SDK reports. **The integer value is also the canonical array index** in a `HandJointInfo[]` result (`index == (int)HandJointType`). Ordered wrist-first, then each finger base-to-tip.

| Joint | Index | Joint | Index |
|---|---|---|---|
| `Wrist` | `0` | `MiddleProximal` | `11` |
| `ThumbTrapezium` | `1` | `MiddleIntermediate` | `12` |
| `ThumbMetaCarpal` | `2` | `MiddleDistal` | `13` |
| `ThumbProximal` | `3` | `MiddleTip` | `14` |
| `ThumbDistal` | `4` | `RingProximal` | `15` |
| `ThumbTip` | `5` | `RingIntermediate` | `16` |
| `IndexProximal` | `6` | `RingDistal` | `17` |
| `IndexIntermediate` | `7` | `RingTip` | `18` |
| `IndexDistal` | `8` | `LittleMetaCarpal` | `19` |
| `IndexTip` | `9` | `LittleProximal` | `20` |
| | | `LittleIntermediate` | `21` |
| | | `LittleDistal` | `22` |
| | | `LittleTip` | `23` |

:::note
The thumb and little finger carry an extra base joint (`ThumbTrapezium` / `LittleMetaCarpal`) the other fingers do not. Iterate a single finger with [`JointSequence`](#jointsequence) rather than hard-coding index ranges.
:::

## Hand helpers

Static helper/extension types that operate on the model above. Each is small and behavior-only — they cluster here rather than on their own pages.

| Type | Namespace | Kind | What it does |
|---|---|---|---|
| [`HandJointInfoExtensions`](#handjointinfoextensions) | `AR51.Unity.SDK` | static ext. on `HandJointInfo[]` | extract joint positions, gated on confidence |
| [`HandJointTypes`](#handjointtypes) | `AR51.Unity.SDK` | static | `GetTypes()` — all `HandJointType` values in index order |
| [`HandJointTypeExtensions`](#handjointtypeextensions) | `AR51.Unity.SDK` | static ext. on `HandJointType` | `IsTip()` — is this a fingertip |
| [`JointSequence`](#jointsequence) | `AR51.Unity.SDK` | static | per-finger joint orderings, base-to-tip |
| [`HandsAdapterExtensions`](#handsadapterextensions) | `AR51.Unity.SDK.Utilities` | static ext. on `IHandsAdapter` / `HandJointInfo[]` | fetch + uniformly scale joints about the wrist |
| [`HandJointTypeMapping`](#handjointtypemapping) | `AR51.Unity.SDK.Utilities` | static ext. on `HandJointType` | map SDK joints to Unity `HumanBodyBones` |
| [`AnimatorHandsExtensions`](#animatorhandsextensions) | `AR51.Unity.SDK.Utilities` | static ext. on `Animator` | pull hand/finger bone `Transform`s off a humanoid rig |

### HandJointInfoExtensions

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

```csharp
public static class HandJointInfoExtensions   // AR51.Unity.SDK
```

Helpers for extracting positions from a joint array (e.g. the result of `GetLeftJointInfos`/`GetRightJointInfos`).

| Method | Returns | Description |
|---|---|---|
| `GetConfidentPositions(this HandJointInfo[] jointsInfo, float minimumConfidence)` | `Vector3[]` | all joint positions if the array meets the confidence threshold, otherwise an empty array. ⚠️ confidence is checked only against the first element (`jointsInfo[0]`), treated as the whole-hand gate |
| `GetPositions(this HandJointInfo[] jointsInfo)` | `Vector3[]` | every joint's `Position` (meters) in array order, unconditionally |
| `HasConfidentPositions(this HandJointInfo[] jointsInfo, float minimumConfidence)` | `bool` | `true` if the array is non-null, non-empty, and `jointsInfo[0].Confidence >= minimumConfidence` |

### HandJointTypes

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

```csharp
public static class HandJointTypes   // AR51.Unity.SDK
```

| Method | Returns | Description |
|---|---|---|
| `GetTypes()` | `HandJointType[]` | all `HandJointType` values in declaration (and therefore index) order |

### HandJointTypeExtensions

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

```csharp
public static class HandJointTypeExtensions   // AR51.Unity.SDK
```

| Method | Returns | Description |
|---|---|---|
| `IsTip(this HandJointType type)` | `bool` | `true` if the joint is a fingertip (`ThumbTip`, `IndexTip`, `MiddleTip`, `RingTip`, `LittleTip`) |

### JointSequence

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

```csharp
public static class JointSequence   // AR51.Unity.SDK
```

Returns per-finger joint orderings, base-to-tip. Useful for drawing or iterating a single finger.

| Method | Sequence (base → tip) |
|---|---|
| `GetThumbSequence()` | Trapezium → MetaCarpal → Proximal → Distal → Tip |
| `GetIndexSequence()` | Proximal → Intermediate → Distal → Tip |
| `GetMiddleSequence()` | Proximal → Intermediate → Distal → Tip |
| `GetRingSequence()` | Proximal → Intermediate → Distal → Tip |
| `GetPinkySequence()` | LittleMetaCarpal → Proximal → Intermediate → Distal → Tip |

Each returns `HandJointType[]`.

<Example inferred>

```csharp
HandJointInfo[] joints = adapter.GetRightJointInfos();

foreach (HandJointType jt in JointSequence.GetIndexSequence())
{
    HandJointInfo j = joints[(int)jt];   // index == (int)HandJointType
    // draw j.Position … (Unity world meters)
}
```

</Example>

### HandsAdapterExtensions

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

```csharp
public static class HandsAdapterExtensions   // AR51.Unity.SDK.Utilities
```

Convenience helpers for retrieving and uniformly scaling hand joints about the wrist. The `ScaleJoints*` overloads extend [`IHandsAdapter`](/docs/sdk-api/unity-api/classes/adapters); `ApplyScale` extends a `HandJointInfo[]`.

| Method | Returns | Description |
|---|---|---|
| `ScaleJointsLeft(this IHandsAdapter adapter, float scale)` | `HandJointInfo[]` | gets the left-hand joints and returns them scaled by `scale` about the wrist |
| `ScaleJointsRight(this IHandsAdapter adapter, float scale)` | `HandJointInfo[]` | same for the right hand |
| `ApplyScale(this HandJointInfo[] joints, float scale)` | `HandJointInfo[]` | uniformly scales all joint positions by `scale` around a wrist-anchored frame (built from wrist, index-proximal, little-proximal). Returns the input unchanged if null/empty. ⚠️ mutates the passed array in place (also returns it); requires a full, index-ordered joint array |

### HandJointTypeMapping

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

```csharp
public static class HandJointTypeMapping   // AR51.Unity.SDK.Utilities
```

Maps SDK hand joints to Unity's `HumanBodyBones` for driving a humanoid `Animator`.

| Method | Returns | Description |
|---|---|---|
| `ToHumanBodyBones(this HandJointType joint, HandType hand)` | `HumanBodyBones` | the matching humanoid bone for the given joint and hand |
| `ToRightHumanBodyBones(this HandJointType joint)` | `HumanBodyBones` | right-hand mapping. Throws `ArgumentOutOfRangeException` for an unmapped joint (e.g. any `*Tip`). Some joints collapse onto `RightHand` (`Wrist`, `ThumbTrapezium`, `LittleMetaCarpal`) |
| `ToLeftHumanBodyBones(this HandJointType joint)` | `HumanBodyBones` | left-hand equivalent, same behavior |

### AnimatorHandsExtensions

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

```csharp
public static class AnimatorHandsExtensions   // AR51.Unity.SDK.Utilities
```

Helpers for pulling hand/finger bone `Transform`s off a humanoid `Animator`.

| Method | Returns | Description |
|---|---|---|
| `GetBoneTransformChild(this Animator animator, HumanBodyBones bone)` | `Transform` | the first child transform of the given humanoid bone. Throws `NullReferenceException` if the bone is missing or has no children |
| `GetHandJoints(this Animator animator, HandType hand)` | `Transform[]` | the hand's joint transforms (delegates to the left/right variant) |
| `GetRightHandJoints(this Animator animator)` | `Transform[]` | 17 right-hand joint transforms in SDK joint order (wrist + per-finger phalanges; tips omitted). Requires a humanoid rig with the mapped bones present |
| `GetLeftHandJoints(this Animator animator)` | `Transform[]` | left-hand equivalent |
| `GetQuestRightFingerJoints(this Animator animator)` | `Transform[]` | right-hand finger transforms in Oculus Quest finger-tracking order. Tips are resolved as `GetChild(0)` of the distal bone, so the rig must have those leaf transforms |
| `GetQuestLeftFingerJoints(this Animator animator)` | `Transform[]` | left-hand equivalent |

## See also

- [Adapters](/docs/sdk-api/unity-api/classes/adapters) — `IHandsAdapter` / `HandsAdapterFactory` that produce the `HandJointInfo[]` documented here
- [Scene components](/docs/sdk-api/unity-api/classes/scene-components) — in-scene hand adapters that report assigned `Transform`s as `HandJointInfo`
- [Extensions](/docs/sdk-api/unity-api/classes/extensions) — other SDK extension helpers
- [Class index](/docs/sdk-api/unity-api/classes) — all Unity SDK types
