Skip to main content

SkeletonConsumer

class Unity component singleton
public class SkeletonConsumer : Singleton<SkeletonConsumer>, ISkeletonListener

Inherits: Singleton<SkeletonConsumer> — a MonoBehaviour base. Reach the live instance with SkeletonConsumer.Instance. Implements: ISkeletonListener (its OnSkeleton(...) callback is how incoming frames are delivered).

The heart of the SDK runtime. Drop one on a GameObject in the scene; it receives Skeleton messages from CVS, keeps a Person per tracked skeleton, instantiates an AR51Character prefab for each, and applies smoothing / scaling / IK / foot-contact every LateUpdate. Configure character prefabs and tuning in the Inspector; subscribe to its events to react to detection and person-lifecycle changes. Acts as a singleton.

Units

The AR 51 Unity SDK works in meters (positions/lengths) and degrees (angles). All joint positions read through Person.Positions, HeadPosition, etc. are Unity world-space Vector3 in meters.

How-to

This page is reference (facts only). For the step-by-step connect → skeleton → drive a character walkthrough, see the How-to guide.

Properties

State & collections

The live set of tracked Persons, plus the singleton accessor. Iterate Persons to read joints each frame.

PropertyTypeAccessDescription
Singleton
InstanceSkeletonConsumerstatic getthe singleton in the scene
Persons
ActivePersonPersongetthe local / nearest-to-camera person (headset/AR)
PersonsIEnumerable<Person>getall currently-tracked persons
PersonByIdDictionary<string, Person>gettracked persons keyed by Skeleton.Id
ActiveSkeletonGameObjectget / setthe active (local) skeleton GameObject
Active character
DefaultCharacterAR51Charactergetthe default prefab applied when none is pinned
ActiveCharacterPrefabAR51Charactergetthe prefab currently on the active person
Timing
CVSTimeDifferencedoublefieldTime.time − CVS PyTime, seconds

Character prefab configuration

Assign these in the Inspector. They select which AR51Character prefab is spawned for each tracked person — globally, or pinned per entity id / display name.

FieldTypeDefaultDescription
Prefabs
CharacterPrefabsAR51Character[]the drivable character prefabs to spawn
CharacterPrefabByEntityIdCharacterMapping[]pin a prefab by external EntityId
CharacterPrefabByEntityDisplayNameCharacterMapping[]pin a prefab by external display name
CharacterPrefabOverrideBySkeletonIdDictionary<string,string>runtime override of prefab name by skeleton Id
UseTitleAsPrefabboolfalseuse the server-requested prefab name (Skeleton.CharacterPrefab)

Inspector tuning knobs

Many [Header]-grouped public fields tune visibility, smoothing, scaling, solvers, and bounds. Names/units are as shown in the Inspector; lengths are meters, angles degrees.

FieldTypeDefaultDescription
Visibility
MoveLimbsbooltruedrive limb IK
ShowModelbooltruerender the character mesh
ShowSkeletonbooltruedraw the skeleton
ShowControllersbooltruedraw controller meshes
ShowSkeletonGizmoboolfalsedraw the skeleton gizmo
Gating
IgnoreUnidentifiedboolfalsedrop skeletons with no entity id
IgnoreOutOfBoundsboolfalsedrop skeletons outside ActiveBounds
ActiveBoundsBoundsbounds (meters) for accepting skeletons
IgnoreLowConfidencebooltruedrop low-confidence joints
UpdateSkeletonbooltrueapply incoming skeleton data each frame
UpdateIkbooltruerun IK each frame
UpdateFingerRotationsbooltrueapply finger rotations
Rotation
EnableClavicleRotationbooltruerotate clavicles
EnableSpineRotationbooltruerotate spine
CopyHeadRotationFromCameraboolfalsedrive head rotation from the main camera
Scaling
AutoScaleModeAutoScaleModeNonUniformhow bone lengths rescale to the person
HandAutoScaleModeHandAutoScaleModeDisabledhand-scaling mode
UniformScalefloat10..2 world scale applied to all positions
MinTorsoSpanInMeters / MaxTorsoSpanInMetersfloat0.2 / 1torso-span clamp (meters)
MinArmSpanInMeters / MaxArmSpanInMetersfloat0.22 / 0.9arm-span clamp (meters)
MinLegSpanInMeters / MaxLegSpanInMetersfloat0.35 / 1.1leg-span clamp (meters)
Ground
GroundYfloat0ground plane height (meters)
GroundPlaneTransformtransform defining the ground
Lifecycle
DestroyInactivePersonsbooltruedestroy models for stale persons
InactivePersonMaxSecondsfloat1seconds without updates before removal
MinSkeletonUpdateBeforeBirthint5updates required before a Person is created
Solvers
FootSolverFootSolversDefault / Plainer / Advanced
FootAdvancedSolverFootAdvancedSolversMoveAndRotateHips / MoveHipsOnly / MoveKnee
HandSolverHandSolversDefault / Advanced
FootContactParametersFootContactParametersfoot-contact tuning
Web streaming
StreamToWebboolfalsemirror frames to a web endpoint
StreamToWebUristringthe web stream URI

⚠️ Many more [Header]-grouped public fields exist for smoothing, foot-contact, finger and scale tuning — they are Inspector knobs with the names/units shown above.

Method summary

Static

MethodReturns
InstanceSkeletonConsumerstatic (property)

Instance — lookup

MethodReturns
TryGetPersonbool
GetPersonPerson
GetPersonIdstring
GetDevicePerson / GetDeviceCharacterPerson / AR51Character
TryGetPrefabByNamebool

Instance — characters

MethodReturns
SetActiveCharacterbool
OverrideCharactervoidoverloads
NextCharactervoid
SetCharacterbooldeprecated
ResetCharacter / ResetCharactersvoid

→ Full descriptions in Method details below.

Events

EventHandler / EventHandler<T>. Subscribe with += in C# (e.g. on Start), unsubscribe with -= on teardown.

EventArgsFires when
OnActivePersonChangedEventHandlerthe active Person changed
OnActiveSkeletonChangedEventHandlerthe active (local) skeleton GameObject changed
OnCvsSkeletonReceivedSkeletonEventArgsa raw skeleton arrived from CVS (before queue/playback gating)
OnSkeletonReceivedSkeletonEventArgsa skeleton is about to be processed this frame
OnPersonCreatedPersonEventArgsa new Person/character was instantiated
OnPersonDeletingPersonEventArgsa Person is about to be removed (model still alive)
OnPersonDeletedPersonEventArgsa Person has been removed (model destroyed)

A Person is created after MinSkeletonUpdateBeforeBirth updates (default 5) and removed after InactivePersonMaxSeconds (default 1) without updates (when DestroyInactivePersons).

Example
// Spawn a log line per new character:
SkeletonConsumer.Instance.OnPersonCreated += (s, e) =>
Debug.Log($"Spawned character for {e.Person.Id}");

Method details

Instance

propertystatic
public static SkeletonConsumer Instance { get; }

The singleton consumer in the scene — the usual way to reach it from anywhere.

ReturnsSkeletonConsumerthe singleton, or null if none is in the scene
Example
var consumer = SkeletonConsumer.Instance;
foreach (var person in consumer.Persons)
Debug.Log(person.Positions[Joints.RWrist]); // right wrist in meters, world space

TryGetPerson

method
public bool TryGetPerson(string personId, out Person person);

Look up a tracked person by id.

Parameters
personIdstringa Skeleton.Id / Person.Id
personPersonreceives the person if tracked
Returnsbooltrue if a person with that id is tracked
Example
if (SkeletonConsumer.Instance.TryGetPerson(personId, out var person))
Debug.Log(person.HeadPosition); // meters, world space

GetPerson

method
public Person GetPerson(Transform t);
public string GetPersonId(Transform t);

The person (or its id) owning the character under a scene Transform — handy from collision/raycast hits on a character mesh.

Parameters
tTransformany transform within a spawned character
ReturnsPersonthe owning person, or null
Example
void OnTriggerEnter(Collider other)
{
var person = SkeletonConsumer.Instance.GetPerson(other.transform);
if (person != null)
Debug.Log($"Hit character of person {person.Id}");
}

GetDevicePerson

method
public Person GetDevicePerson(string deviceId);
public AR51Character GetDeviceCharacter(string deviceId);

Resolve the person / character associated with a given originating device id (see Skeleton.DeviceId).

Parameters
deviceIdstringthe originating device id
ReturnsPersonthe matching person, or null

TryGetPrefabByName

method
public bool TryGetPrefabByName(string prefabName, out AR51Character prefab);

Look up an AR51Character prefab in CharacterPrefabs by name.

Parameters
prefabNamestringname of a prefab in CharacterPrefabs
prefabAR51Characterreceives the prefab if found
Returnsbooltrue if a prefab with that name exists

SetActiveCharacter

method
public bool SetActiveCharacter(string characterPrefabName);

Change the active person's prefab to a named entry in CharacterPrefabs.

Parameters
characterPrefabNamestringname of an AR51Character prefab in CharacterPrefabs
Returnsbooltrue if the swap succeeded (prefab found)
Example
// Swap the active person's mesh to a named character prefab at runtime
if (!SkeletonConsumer.Instance.SetActiveCharacter("RobotCharacter"))
Debug.LogWarning("Prefab not found in CharacterPrefabs");

OverrideCharacter

methodoverloads
public void OverrideCharacter(string personId, string overridePrefabName);
public void OverrideCharacter(Person person, string overridePrefabName);

Pin a specific prefab to one person (overrides auto-assignment). Use for deterministic casting; otherwise rely on AutoScaleMode / CharacterPrefabByEntityId mapping.

Parameters
personIdstringthe person to override (or pass the Person)
overridePrefabNamestringprefab name to use for that person
Example
// Always cast a specific tracked person as a named prefab
SkeletonConsumer.Instance.OverrideCharacter(personId, "GuestAvatar");

NextCharacter

method
public void NextCharacter(int indexIncrease = 1);

Cycle the default prefab forward through CharacterPrefabs by indexIncrease entries.

Parameters
indexIncreaseint ?how many prefabs to advance (default 1)

SetCharacter

methoddeprecated
public bool SetCharacter(string characterPrefabName);

⚠️ Deprecated. Sets the default prefab for all persons. Prefer SetActiveCharacter (active person) or OverrideCharacter (a specific person).

Returnsbooltrue if the prefab was found

ResetCharacters

method
public void ResetCharacter(string personId); // destroy that person's model
public void ResetCharacters(); // destroy all spawned models, clear assignment

Destroy spawned character models and clear assignment — one person, or all of them.

Parameters
personIdstringthe person whose model to destroy (single-person overload)
Example
// Drop everything and let characters respawn from the next frames
SkeletonConsumer.Instance.ResetCharacters();

Nested enums

property
public enum FootSolvers { Default, Plainer, Advanced }
public enum FootAdvancedSolvers { MoveAndRotateHips, MoveHipsOnly, MoveKnee }
public enum HandSolvers { Default, Advanced }

Solver selectors for the FootSolver / FootAdvancedSolver / HandSolver Inspector fields above.

Internal — not documented

Solve(...) / SolveAll() / OnSkeleton(...) (the ISkeletonListener callback) / NormlizeSkeletonOrigin() [sic] / GetNestedProperties() / GetPersonCollider(...) / GetGroundY() / SetHandsAdapterOverride(...) are public but are driven internally by LateUpdate or by playback — you don't normally call them. The IK/solver math behind the solve is internal and not part of the documented surface.

See also

Was this page helpful?