Skip to main content

USkeletonConsumer

UCLASS · UActorComponent BlueprintSpawnableComponent singleton
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class AR51SDK_API USkeletonConsumer : public UActorComponent, public ISingleton<USkeletonConsumer>

Inherits: UActorComponent (Unreal Engine) · ISingleton<USkeletonConsumer>

The central entry point of the SDK. Drop one on an actor in the level; it connects to the AR 51 skeleton service, spawns/destroys a character per tracked person, drives each one every frame, and fires Blueprint events on person-lifecycle changes. Acts as a singleton.

How-to

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

Properties

All EditAnywhere, BlueprintReadWrite.

PropertyTypeDefaultDescription
General
ShowModelbooltruerender the character mesh
ShowSkeletonboolfalsedraw the skeleton gizmo
ShowControllersboolfalsedraw controller meshes
MaxSkeletonCountint320cap on tracked skeletons (0 = unlimited)
CharacterBlueprintsTArray<TSubclassOf<AActor>>candidate AAR51CharacterActor BPs to spawn
UpdateSkeletonbooltrueapply incoming skeleton data each frame
IsApplyHeadRotationWristPositionAndFingerRotationsbooltruefuse device head rotation + wrist/finger poses
SkeletonPredictionSettingsFPredictionSettingssmoothing / extrapolation model
HandTrackingFallbackSmoothingFactorfloat0.99smoothing when falling back to hand tracking
SolverParametersFSolverParamsIK / auto-scale settings
Visualization
ControllerMeshUStaticMesh*mesh drawn for controllers
ControllerSizefloat0.1controller mesh scale
SkeletonMeshUStaticMesh*mesh drawn per skeleton joint
SkeletonSizefloat0.025joint mesh scale
Debug
bShowDebugBoundsboolfalsedraw person bounds
DebugBoxColorFColorGreenbounds box color
DebugSphereColorFColorRedbounds sphere color
Character instantiation
ActivePersonCameraSpaceEActivePersonCameraSpaceComponentSpacespace used to pick the active person
MaxCameraDistanceThresholdfloat20⚠️ max distance (m?) for active-person selection
DestroyInactivePersonsbooltruedestroy models for stale persons
InactivePersonMaxSecondsfloat1.0seconds without updates before removal
HidePersonMaxSecondsfloat0.2seconds without updates before hiding
Character mapping
AutoCharacterAssignmentModeEAutoCharacterAssignmentModeDefaulthow characters are auto-assigned (Default / Cycle / Random)
PersonIdToCharacterBPMapTMap<FString,FString>pin character BP by mocap PersonId
EntityIdToCharacterBPMapTMap<FString,FString>pin by external EntityId
EntityDisplayNameToCharacterBPMapTMap<FString,FString>pin by external display name
Recording
IsRecordingboolfalserecord incoming frames to InOutRecordingFile
IsPlaybackboolfalsereplay from InOutRecordingFile instead of the live stream
IsPlaybackLoopboolfalseloop playback
InOutRecordingFileFString"/Recordings/file.txt"record/playback file path

Method summary

Static

MethodReturns
GetSkeletonConsumerSingletonUSkeletonConsumer*BlueprintCallable

Instance

MethodReturns
ConnectvoidBlueprintCallable
DisconnectvoidBlueprintCallable
IsConnectedboolBlueprintCallable
GetEndpointFStringBlueprintCallable
GetActivePersonTScriptInterface<IPersonBase>BlueprintCallable
GetPersonByPersonIdTScriptInterface<IPersonBase>BlueprintCallable
GetPersonByEntityId / …DisplayNameTScriptInterface<IPersonBase>BlueprintCallable
GetPersonByIdTMap<FString, …>BlueprintCallable
GetCharactersTArray<UAR51Character*>BlueprintCallable
SetActiveCharacterboolBlueprintCallable
FindCharacterIndexByNameint32BlueprintCallable
SetCharacterBy…voidBlueprintCallable · overloads
ResetCharacter / …CharactersvoidBlueprintCallable
GetMainCameraComponent / SetMainCameraComponentUCameraComponent*BlueprintCallable
GetLastCaptureTimedoubleBlueprintCallable

→ Full descriptions in Method details below.

Events

UPROPERTY(BlueprintAssignable), dynamic multicast. Bind in C++ with AddDynamic, or as a red event node in Blueprint.

EventSignatureFires when
OnPersonDetectedFOnPersonDetected(FString PersonId)a person is detected for the first time (character spawned)
OnPersonUpdatedFOnPersonUpdated(FString PersonId)a person's skeleton data is updated (per-frame-ish)
OnPersonTrackingLostFOnPersonTrackingLost(FString PersonId)tracking for a person is lost
OnPersonTrackingRecoveredFOnPersonTrackingRecovered(FString PersonId)tracking recovers after being lost
OnPersonDestroyedFOnPersonDestroyed(FString PersonId)a person is destroyed (lost tracking too long)
OnActivePersonChangedFOnActivePersonChanged(FString PersonId)the headset-associated active person changes — PersonId is "" when none

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

Method details

GetSkeletonConsumerSingleton

methodstaticBlueprintCallable
static USkeletonConsumer* GetSkeletonConsumerSingleton();

The live consumer instance — the usual way to reach it from anywhere. (Deprecated alias: GetSingleton().)

ReturnsUSkeletonConsumer*the singleton, or nullptr if none is in the level

Connect

methodBlueprintCallable
void Connect(const FString& endpoint);

Connects to the AR 51 skeleton service and starts the background consume loop; characters begin appearing as people are detected. Call once (e.g. on BeginPlay).

Parameters
endpointFStringthe skeleton service address as "IP:Port"
Exampleinferred
void AMyManager::BeginPlay()
{
Super::BeginPlay();
auto* Consumer = USkeletonConsumer::GetSkeletonConsumerSingleton();
Consumer->OnPersonDetected.AddDynamic(this, &AMyManager::HandlePersonDetected);
Consumer->Connect(TEXT("127.0.0.1:50052")); // ⚠️ exact port depends on your OMS/skeleton service
}

Disconnect

methodBlueprintCallable
void Disconnect();

Tears down the connection and stops consuming frames. Call on EndPlay.

IsConnected

methodBlueprintCallable
bool IsConnected() const;
Returnsbooltrue while the stream is live

GetEndpoint

methodBlueprintCallable
FString GetEndpoint() const;
ReturnsFStringthe current endpoint as "IP:Port"

GetActivePerson

methodBlueprintCallable
TScriptInterface<IPersonBase> GetActivePerson();

The person currently associated with the headset/camera (nearest/local) — the one you usually drive first-person logic or UI from.

ReturnsTScriptInterface<IPersonBase>the active person, or null if none is associated with the headset
Exampleinferred
if (UObject* P = Consumer->GetActivePerson().GetObject())
{
UAR51Character* Char = IPersonBase::Execute_GetCharacter(P);
const FVector Head = Char->GetHeadPosition(); // UE cm
}

GetPersonByPersonId

methodBlueprintCallable
TScriptInterface<IPersonBase> GetPersonByPersonId(const FString& PersonId);

Look up a tracked person by the mocap system's per-person id.

Parameters
PersonIdFStringthe mocap PersonId (see Id semantics on IPersonBase)
ReturnsTScriptInterface<IPersonBase>the person, or null if not tracked
Exampleinferred
if (UObject* P = Consumer->GetPersonByPersonId(PersonId).GetObject())
{
if (IPersonBase::Execute_IsTracked(P))
UE_LOG(LogTemp, Log, TEXT("Tracking %s"), *IPersonBase::Execute_GetId(P));
}

GetPersonByEntityId

methodBlueprintCallable
TScriptInterface<IPersonBase> GetPersonByEntityId(const FString& EntityId);
TScriptInterface<IPersonBase> GetPersonByEntityDisplayName(const FString& Name);

Look up a person by the external-system entity id or display name (as opposed to the mocap PersonId).

ReturnsTScriptInterface<IPersonBase>the matching person, or null

GetPersonById

methodBlueprintCallable
const TMap<FString, TScriptInterface<IPersonBase>>& GetPersonById();
ReturnsTMap<FString, …IPersonBase>all currently-tracked persons, keyed by PersonId

GetCharacters

methodBlueprintCallable
TArray<UAR51Character*> GetCharacters() const;
ReturnsTArray<UAR51Character*>every tracked character component
Exampleinferred
for (UAR51Character* Char : Consumer->GetCharacters())
{
const FVector L = Char->GetLeftWristPosition(); // UE cm
const FVector R = Char->GetRightWristPosition();
}

SetActiveCharacter

methodBlueprintCallable
bool SetActiveCharacter(const FString& characterBPName);

Swap the active person's character to a named Blueprint from CharacterBlueprints.

Parameters
characterBPNameFStringname of a Blueprint in CharacterBlueprints
Returnsbooltrue if the swap succeeded
Exampleinferred
// Swap the active person's mesh to a named character BP at runtime
if (!Consumer->SetActiveCharacter(TEXT("BP_RobotCharacter")))
UE_LOG(LogTemp, Warning, TEXT("Character BP not found in CharacterBlueprints"));

FindCharacterIndexByName

methodBlueprintCallable
int32 FindCharacterIndexByName(const FString& CharacterBPName);
Parameters
CharacterBPNameFStringBlueprint name to find
Returnsint32index into CharacterBlueprints, or -1 if not found

SetCharacterBy

methodBlueprintCallableoverloads
void SetCharacterByPersonId(const FString& PersonId, const FString& CharacterBPName);
void SetCharacterIndexByPersonId(const FString& PersonId, int32 Index);
void SetCharacterByEntityId(const FString& EntityId, const FString& CharacterBPName);
void SetCharacterIndexByEntityId(const FString& EntityId, int32 Index);
void SetCharacterByEntityDisplayName(const FString& Name, const FString& CharacterBPName);
void SetCharacterIndexByEntityDisplayName(const FString& Name, int32 Index);

Pin a specific character Blueprint (by name or index) to a person, keyed by PersonId, EntityId, or display name. Use these for deterministic casting; otherwise rely on AutoCharacterAssignmentMode.

ResetCharacters

methodBlueprintCallable
void ResetCharacter(const FString& PersonId); // remove that person + destroy its model
void ResetActiveCharacter(); // same, for the active person
void ResetCharacters(); // destroy all spawned models, clear tracking

Main camera

methodBlueprintCallable
UCameraComponent* GetMainCameraComponent() const;
void SetMainCameraComponent(UCameraComponent*);

The camera used for head tracking / active-person selection. Override auto-detection with the setter when your rig has more than one camera.

ReturnsUCameraComponent*the camera in use

GetLastCaptureTime

methodBlueprintCallable
double GetLastCaptureTime() const;
Returnsdoubleserver-side capture timestamp of the last frame — seconds since Unix epoch (1970 UTC)

See also

Was this page helpful?