UAR51Character
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class AR51SDK_API UAR51Character : public UPoseableMeshComponent
Inherits: UPoseableMeshComponent (Unreal Engine)
The mocap-driven mesh: the skeletal mesh that gets posed from AR 51 skeleton data. It maps each canonical AR 51 bone name onto the target skeleton (via AR51Mapping), then on each frame Solve(...) writes the bone transforms through the IK / auto-scale / smoothing pipeline. Normally spawned and owned by USkeletonConsumer inside an AAR51CharacterActor — you rarely construct one by hand.
This is an Unreal class, so all positions and lengths are UE centimetres and rotations are quaternions/degrees. The joint positions passed to Solve are indexed by Keypoints and are in UE world-space cm ⚠️ — AR 51 mocap data is natively in metres, so the metres→cm scaling happens at the consumer/Solve boundary. See the ⚠️ on Solve below.
IK solving, calf/hand correction math, auto-scale, body and finger smoothing, and forearm-twist computation are black boxes. The only public knobs are the properties below plus FSolverParams on USkeletonConsumer::SolverParameters.
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.
| Property | Type | Default | Description |
|---|---|---|---|
| General | |||
AR51Mapping | UAR51SkeletonMapping* | — | preferred per-skeleton bone-mapping asset |
SkeletonMapping | UNodeMappingContainer* | — | legacy fallback mapping, used only if AR51Mapping is unset |
| IK Solver | |||
bOverrideCalfCorrectionScale | bool | false | enable the per-character calf/ankle correction override |
CalfCorrectionScaleOverride | float | 0.95 | per-character calf/ankle correction, overrides the global solver value (clamp 0–2; 1.0 = no correction) |
bOverrideHandCorrectionScale | bool | false | enable the per-character hand-scale correction override |
HandCorrectionScaleOverride | float | 0.95 | per-character hand-scale correction (clamp 0–2; 1.0 = no correction) |
| IK Solver | Twist | |||
LeftForearmTwistBones | TArray<FBoneWeight> | — | left forearm twist-distribution chain |
RightForearmTwistBones | TArray<FBoneWeight> | — | right forearm twist-distribution chain |
Method summary
Drive (per-frame pipeline) — normally called for you by USkeletonConsumer.
| Method | Returns | |
|---|---|---|
Solve | void | C++ only |
SolveHands | void | C++ only |
ApplyOnSkeletalMeshes | void | C++ only |
Setup
| Method | Returns | |
|---|---|---|
Initialize | void | BlueprintCallable |
GetSkeletonId | FString | BlueprintCallable |
SetSkeletonId / GetDeviceId / SetDeviceId | void / FString | C++ only |
GetBoneName | FName | C++ only |
ValidateMapping | bool | C++ only |
Pose read/write
| Method | Returns | |
|---|---|---|
SetBoneLocalTransformByName | void | BlueprintCallable |
GetBoneLocalTransformByName | FTransform | BlueprintCallable |
GetHeadPosition | FVector | C++ only |
GetHeadRotation / SetHeadRotation | FQuat / void | C++ only |
GetLeftWristPosition / GetRightWristPosition | FVector | C++ only |
GetLeftHandJoints / GetRightHandJoints | TArray<TSharedPtr<BoneTransform>> | C++ only |
→ Full descriptions in Method details below.
Method details
Solve
void Solve(const TArray<FVector>& positions, const TArray<float>& confidence, bool SolveHands = true);
The core drive call. Poses the whole skeleton from one frame of joint positions plus per-joint confidence, running the IK / auto-scale / smoothing pipeline (a black box). USkeletonConsumer calls this every frame; you only call it on the manual/advanced path.
positionstrue)Whether positions are world-space or component-space, and which side owns the metres→cm scaling at this boundary, is unconfirmed. AR 51 mocap data is metres; UE is cm. Verify before driving manually.
// Manual/advanced path only — the consumer normally does this for you.
Character->Initialize(); // once, after AR51Mapping is set
// per frame:
Character->Solve(Positions, Confidence); // Positions indexed by Keypoints, UE world-space cm
Character->ApplyOnSkeletalMeshes(); // push the solved pose to the rendered mesh
SolveHands
void SolveHands(const TArray<FVector>& lHandPos, const TArray<FVector>& rHandPos);
Pose just the finger joints from hand keypoint positions (UE cm). Useful when body and hands arrive on separate cadences; Solve(..., SolveHands=true) already covers the combined case.
ApplyOnSkeletalMeshes
void ApplyOnSkeletalMeshes();
Push the solved pose onto the rendered mesh(es). Call after Solve / SolveHands on the manual path; in the normal flow the consumer does this for you.
Initialize
void Initialize();
Build the bone mapping and internal solver state from AR51Mapping. Call once before driving the character. The consumer calls it for spawned characters; call it yourself only on the manual path.
GetSkeletonId
FString GetSkeletonId() const;
Id & device wiring
void SetSkeletonId(const FString& Id);
FString GetDeviceId() const;
void SetDeviceId(const FString& Id);
Low-level id/device plumbing, set up by the consumer when it spawns the character. Read GetDeviceId() to find which capture device a character is bound to.
GetBoneName
FName GetBoneName(FName& name);
Resolve a canonical AR 51 bone name to the corresponding target-skeleton bone name via the active mapping.
ValidateMapping
bool ValidateMapping(const TArray<FName>& requiredBoneNames);
Check that the mapping covers every required canonical bone — a useful guard before Solve.
true if all required canonical bones resolve to a target bonestatic const TArray<FName> Required = { TEXT("Hips"), TEXT("Head"), TEXT("LeftHand"), TEXT("RightHand") };
if (!Character->ValidateMapping(Required))
UE_LOG(LogTemp, Warning, TEXT("AR51Mapping is missing required bones — Solve may misbehave"));
SetBoneLocalTransformByName
void SetBoneLocalTransformByName(FName BoneName, const FTransform& InTransform);
Set a bone's local (parent-space) transform on the poseable mesh. Lets you override or post-process the solved pose (e.g. additive props) before ApplyOnSkeletalMeshes.
GetBoneLocalTransformByName
FTransform GetBoneLocalTransformByName(FName BoneName);
Read a bone's local (parent-space) transform.
GetHeadPosition
FVector GetHeadPosition();
// From a tracked person, read the driven character's head position (UE cm).
if (UObject* P = Consumer->GetActivePerson().GetObject())
{
UAR51Character* Char = IPersonBase::Execute_GetCharacter(P);
const FVector Head = Char->GetHeadPosition(); // UE world-space cm
}
Head rotation
FQuat GetHeadRotation();
void SetHeadRotation(const FQuat& Rotation);
Read or write the head-bone world rotation. SetHeadRotation is how headset orientation is fused onto the solved skeleton — when USkeletonConsumer::IsApplyHeadRotationWristPositionAndFingerRotations is on, the consumer writes the device's head rotation here.
Wrist positions
FVector GetLeftWristPosition();
FVector GetRightWristPosition();
The solved wrist world positions (UE cm) — handy for attaching props or driving hand UI.
const FVector L = Char->GetLeftWristPosition(); // UE world-space cm
const FVector R = Char->GetRightWristPosition();
AttachedSword->SetActorLocation(R);
Hand joints
const TArray<TSharedPtr<BoneTransform>>& GetLeftHandJoints() const;
const TArray<TSharedPtr<BoneTransform>>& GetRightHandJoints() const;
The live finger-bone handles for each hand — direct access to the per-joint transforms maintained by the solver.
See also
USkeletonConsumer— spawns, owns, and drives this character every frameAAR51CharacterActor— the actor that wraps this componentUAR51SkeletonMapping— the bone-mapping assetAR51Mappingpoints atIPersonBase—GetCharacter()returns theUAR51Characterfor a tracked personBoneTransform— the finger-joint handle typeKeypoints— the joint index order expected bySolveFSolverParams— global IK / auto-scale settings on the consumer- Class index — all Unreal SDK types