Skip to main content

Skeletons & characters

The heart of the SDK: USkeletonConsumer connects to the skeleton stream, spawns/destroys a character per tracked person, drives each UAR51Character every frame, and fires person-lifecycle events.

Units

UE works in centimeters / degrees; AR 51 mocap data is natively meters. Conversion happens inside the SDK before bone driving — by the time positions reach UAR51Character::Solve(...) they appear to be UE world-space cm. ⚠️ The exact layer that scales meters→cm, and whether SkeletonData.Positions handed to callers is meters or cm, is unconfirmed.

USkeletonConsumer​

Moved to USkeletonConsumer.

UAR51Character​

Moved to UAR51Character.

AAR51CharacterActor​

Moved to AAR51CharacterActor.

UAR51SkeletonMapping​

Moved to UAR51SkeletonMapping.

FBoneWeight​

USTRUCT BlueprintType

A single bone + blend weight, used for twist chains: FName Bone; float Weight = 1.0f (clamp 0–1). Both EditAnywhere, BlueprintReadWrite.

UAR51FootBoundsComponent​

Moved to UAR51FootBoundsComponent.

SkeletonData​

Moved to SkeletonData.

Keypoints​

Moved to Keypoints.

IPersonBase​

Moved to IPersonBase.

BoneTransform​

Moved to BoneTransform.

Prediction​

Smoothing / extrapolation knobs, set via USkeletonConsumer::SkeletonPredictionSettings. The predictor classes themselves are C++-only strategy types — you configure them entirely through these structs.

EPredictionModel​

UENUM BlueprintType

None ("No Prediction"), Linear, Kalman ("Kalman Filter").

FPredictionSettings​

USTRUCT BlueprintType
FieldDefaultMeaning
ModelNonewhich model filters/predicts incoming skeleton data
PredictionDeltaTime0.016flook-ahead Δt in seconds (~60 FPS)
MaxPredictionDisplacement5.0fclamp look-ahead displacement (cm)
OutlierThreshold50.fignore per-frame spikes above this (cm)
Linear—FLinearPredictionTuning (shown when Model==Linear)
Kalman—FKalmanPredictionTuning (shown when Model==Kalman)

FLinearPredictionTuning — VelocitySmoothingAlpha{0.92} (0–1; higher = smoother), MaxVelocity{800.f} (cm/s), ConfidenceMinForVelocity{0.2} (0–1).

FKalmanPredictionTuning — AccelStd{200.f} (cm/s²; higher = more responsive), MeasurementNoisePos{2.0} (cm²; higher = smoother), bConfidenceWeighting{true} (scale trust by 1 - confidence).

IK solver & auto-scale settings​

FSolverParams​

USTRUCT BlueprintType

Set via USkeletonConsumer::SolverParameters. All EditAnywhere, BlueprintReadWrite:

  • Enabled{true}.
  • CalfCorrectionScale{0.95} — ankle-position correction (1.0 = none); per-character override via UAR51Character.
  • HandCorrectionScale{1.0} — hand auto-scale correction (1.0 = none).
  • MinimumHandsConfidence{0.1} — min headset-hand confidence still solved.
  • EnableLimbPositioning{true}, EnableClavicleRotation{true}.
  • AutoScaleType{Default}, AutoHandScaleType{NoScaling}, FilterType{SimpleSmoothing}.
  • SmoothingFactor{0.995}, MinValidScale{0.2}, MaxValidScale{1.8}.
  • EnableBodySmoothing{true}, TemporalRotationalSmooth{0.75}, TemporalRotationalNeckSmooth{0.75}, EnableFingerSmoothing{true}, TemporalFingersRotationalSmooth{0.75}.
  • Helpers: bool IsValidScale(float), bool IsEnableLimbPositioning().
UENUM BlueprintType
  • EAutoCharacterAssignmentMode — ACAM_Default (first valid character), ACAM_Cycle, ACAM_Random.
  • EAutoScaleFilterType — FT_Default, FT_Kalman, FT_MovingAverage, FT_MovingMedian, FT_SimpleSmoothing.
  • EActivePersonCameraSpace — APCS_ComponentSpace (default, world location), APCS_RelativeSpace (relative within parent).
  • EAutoScaleType — FT_NoScaling, FT_Default.

Walkthrough​

Connect → receive skeleton → drive a character (Blueprint-first; the SDK does the heavy lifting):

  1. Place the consumer. Add a USkeletonConsumer component to an actor (e.g. a "GameManager" actor). Only one is needed — it's a singleton.
  2. Author a mapping asset. Create a UAR51SkeletonMapping, set TargetSkeleton, run AutoMap() (or map in the AR 51 humanoid mapping editor). Check GetValidationSummary shows 0 missing/invalid. ⚠️ exact editor menu/action name unconfirmed.
  3. Make a character actor. Create a Blueprint child of AAR51CharacterActor for your mesh; set its Character's AR51Mapping to the asset from step 2. (Fit Left/RightFootBounds via the character's "Create Foot Bounds" action.) ⚠️ whether AR51Mapping is set on the BP default or wired at spawn is unconfirmed.
  4. Register the character. Add your character BP to USkeletonConsumer::CharacterBlueprints. Optionally map specific people via PersonIdToCharacterBPMap / SetCharacterByPersonId(...), or rely on AutoCharacterAssignmentMode.
  5. Tune (optional). Set SolverParameters and SkeletonPredictionSettings (e.g. Model=Linear). Set the main camera via SetMainCameraComponent if head fusion / active-person selection needs a specific one.
  6. Connect. On BeginPlay, call Connect("IP:Port") (the AR 51 skeleton service endpoint). ⚠️ default/expected endpoint string unconfirmed.
  7. React to people. Bind OnPersonDetected / OnPersonUpdated / OnPersonDestroyed / OnActivePersonChanged. The consumer automatically spawns an AAR51CharacterActor per detected person and drives it every frame (calls Solve(...) internally) — you do not call Solve yourself. Use GetPersonByPersonId(...) / GetActivePerson() → GetCharacter() to read state (head/wrist positions, etc.).
  8. Cleanup. Disconnect() on EndPlay; ResetCharacters() to clear all spawned models.
Manual/advanced path

If you drive a UAR51Character yourself: call Initialize() once, then per frame call Solve(positions, confidence) with positions indexed by Keypoints in UE world-space cm, followed by ApplyOnSkeletalMeshes(). ⚠️ whether positions are world- or component-space, and the meters→cm scaling responsibility at that boundary, is unconfirmed.


Next: Object detection.

Was this page helpful?