reckfellENGINE

XRPositionalTracker

Shared state for named poses and tracking.

On this page
class XRPositionalTrackerReckfellSharpInherits XRTracker

XRPositionalTracker stores state supplied by a tracking provider to XRServer. It is not an Entity or a physics body. Constructing it registers no device and starts no session. XRControllerTracker represents a controller; use XREntity3D or XRController3D in gameplay rigs.

HasPose checks entry existence. InvalidatePose retains the entry, last transform, velocities and confidence while clearing HasTrackingData. SetPose updates the same object and validates it again; even Confidence=None does not clear that flag. Assess data eligibility separately from entry existence.

This executed example copies the raw transform only when tracking is available. It adds no WorldScale, reference frame or gameplay origin and does not assess tracking quality:

C#
using Reckfell;

public static class TrackedPoseReader
{
    // Raw tracking-space pose, not a world transform or a tracking-quality test.
    public static bool TryRead(
        XRPositionalTracker tracker, StringName poseName, out Transform3D transform)
    {
        transform = Transform3D.Identity;
        if (tracker is null) return false;
        // Shared tracker state: do not dispose its cached C# wrapper here.
        var pose = tracker.GetPose(poseName);
        if (pose is null || !pose.HasTrackingData) return false;
        transform = pose.Transform;
        return true;
    }
}

GetPose and event arguments contain shared state. C# may reuse the wrapper for one native object: do not Dispose/use using on a borrowed pose. Testing showed this invalidates another held reference. Copy Transform, velocities and flags for a snapshot.

PoseChanged fires on every SetPose; PoseLostTracking on every InvalidatePose of an existing entry, including repeats. This differs from deduplicated TrackingChanged on XREntity3D. Pose loss does not reset stored input or create ButtonReleased.

The current C# SDK marks GetInput/SetInput Obsolete even through XRControllerTracker. Gameplay reads XRController3D; native Call was used only in an isolated synthetic-provider check. State and the example were checked without a real headset or tracking-quality assessment. Setup: XR components.

Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.

Constructors1

XRPositionalTrackerConstructor
# XRPositionalTracker
C#
public XRPositionalTracker();

Creates a state container with no poses, an empty Profile, Hand=Unknown and Type=Unknown. Does not register with XRServer or discover a device. Use XRControllerTracker for a controller.

Properties2

HandProperty
# Hand
C#
public XRPositionalTracker.TrackerHand Hand { get; set; }

Hand assignment, initially Unknown. Use Unknown, Left or Right; Max is the enum bound, not a device value. The setter checks bounds. Not inferred automatically from Name; creates no pose and emits no ProfileChanged.

ProfileProperty
# Profile
C#
public string Profile { get; set; }

Profile string, initially empty. For OpenXR usually an interaction-profile path; the setter does not validate format or support. ProfileChanged fires only when the string changes and carries the new profile. Does not create a device or switch its capabilities.

Methods10

GetInputVariant · Deprecated
# GetInput
C#
public Variant GetInput(StringName name);

Returns a Variant by internal action name, or Nil. The current C# SDK marks it Obsolete, including when inherited by XRControllerTracker. For gameplay use XRController3D.GetInput; direct access on a base XRPositionalTracker also produces a native warning. Does not check pose or focus.

Parameters
NameTypeDefault
nameStringName—
name

Exact internal action name; not LocalizedName or ordinary InputMap.

Returns Variant

Stored-type Variant or Nil; dispose the returned Variant wrapper with using.

GetPoseXRPose
# GetPose
C#
public XRPose GetPose(StringName name);

Returns shared named-pose state or null. Repeated SetPose updates the same object; not a snapshot. C# may reuse the same wrapper: do not Dispose/use using on borrowed pose state that other references may read. Copy Transform and required values for a snapshot; check HasTrackingData.

Parameters
NameTypeDefault
nameStringName—
name

Exact pose name, such as grip or aim; not a left_hand/right_hand tracker name.

Returns XRPose

Shared pose or null. Do not dispose the borrowed C# wrapper; copy values for a snapshot.

GetTrackerHandXRPositionalTracker.TrackerHand
# GetTrackerHand
C#
public XRPositionalTracker.TrackerHand GetTrackerHand();

Returns stored hand assignment, initially Unknown. Does not establish tracking data availability.

Returns XRPositionalTracker.TrackerHand

Stored hand; initially Unknown.

GetTrackerProfilestring
# GetTrackerProfile
C#
public string GetTrackerProfile();

Returns the stored profile string, initially empty. Not a tracker name, hand or proof of device support.

Returns string

Stored profile; initially an empty string.

HasPosebool
# HasPose
C#
public bool HasPose(StringName name);

Checks whether a named pose entry exists. Remains true after InvalidatePose because the entry is retained. To use the data, inspect GetPose(name) and that pose’s HasTrackingData.

Parameters
NameTypeDefault
nameStringName—
name

Exact pose name, such as grip or aim; not a left_hand/right_hand tracker name.

Returns bool

true when an entry exists, including one with lost tracking.

InvalidatePosevoid
# InvalidatePose
C#
public void InvalidatePose(StringName name);

For an existing pose, clears HasTrackingData and emits PoseLostTracking on every call, including repeats. Does not remove the entry, zero transform/velocities/confidence or reset input. An unknown name does nothing. The next SetPose validates the entry again.

Parameters
NameTypeDefault
nameStringName—
name

Exact pose name, such as grip or aim; not a left_hand/right_hand tracker name.

SetInputvoid · Deprecated
# SetInput
C#
public void SetInput(StringName name, Variant value);

Stores a value by action name; events occur only for changed values and only for Bool, Float or Vector2. Float does not synthesize threshold-based ButtonPressed. The C# SDK marks this method Obsolete even through XRControllerTracker; not a gameplay-input API. The tracking provider owns state; gameplay reads XRController3D. QA used native Call only for synthetic data.

Parameters
NameTypeDefault
nameStringName—
valueVariant—
name

Exact internal action name; not LocalizedName or ordinary InputMap.

value

Action value. Events support Bool, Float and Vector2; provider data, not keyboard simulation.

SetPosevoid
# SetPose
C#
public void SetPose(StringName name, Transform3D transform, Vector3 linearVelocity, Vector3 angularVelocity, XRPose.TrackingConfidenceEnum trackingConfidence);

Creates a missing pose entry or updates the existing object. Stores transform, velocities, confidence and HasTrackingData=true; emits PoseChanged on every call, even for identical values. Confidence=None does not itself clear HasTrackingData. Intended for the tracking provider; gameplay should not replace real-device state.

Parameters
NameTypeDefault
nameStringName—
transformTransform3D—
linearVelocityVector3—
angularVelocityVector3—
trackingConfidenceXRPose.TrackingConfidenceEnum—
name

Exact pose name, such as grip or aim; not a left_hand/right_hand tracker name.

transform

Provider tracking-space transform. Stored without adding the gameplay origin; not the character GlobalTransform.

linearVelocity

Linear velocity in provider conventions; stored as supplied, not computed from previous poses.

angularVelocity

Angular velocity in provider conventions; stored as supplied.

trackingConfidence

Confidence for the entry. None does not prevent SetPose setting HasTrackingData=true; these are distinct fields.

SetTrackerHandvoid
# SetTrackerHand
C#
public void SetTrackerHand(XRPositionalTracker.TrackerHand hand);

Hand assignment, initially Unknown. Use Unknown, Left or Right; Max is the enum bound, not a device value. The setter checks bounds. Not inferred automatically from Name; creates no pose and emits no ProfileChanged.

Parameters
NameTypeDefault
handXRPositionalTracker.TrackerHand—
hand

Unknown, Left or Right; Max is not a valid hand.

SetTrackerProfilevoid
# SetTrackerProfile
C#
public void SetTrackerProfile(string profile);

Profile string, initially empty. For OpenXR usually an interaction-profile path; the setter does not validate format or support. ProfileChanged fires only when the string changes and carries the new profile. Does not create a device or switch its capabilities.

Parameters
NameTypeDefault
profilestring—
profile

Profile string to store. The setter does not verify runtime support; repeating it emits no event.

Signals and events7

ButtonPressedEvent
# ButtonPressed
C#
public event XRPositionalTracker.ButtonPressedEventHandler ButtonPressed;

Emitted for a changed Bool=true write. Repeated true emits nothing; Float does not automatically become a press. Carries the internal action name, not a display label.

Handler parameters
NameTypeDefault
actionNamestring—
actionName

Internal action name, such as select; not a label or controller-component path.

ButtonReleasedEvent
# ButtonReleased
C#
public event XRPositionalTracker.ButtonReleasedEventHandler ButtonReleased;

Emitted for a changed Bool=false write. Pose loss does not reset input or emit a release; clear gameplay interaction state separately.

Handler parameters
NameTypeDefault
actionNamestring—
actionName

Internal action name, such as select; not a label or controller-component path.

InputFloatChangedEvent
# InputFloatChanged
C#
public event XRPositionalTracker.InputFloatChangedEventHandler InputFloatChanged;

Passes a changed Float action value. The C# value parameter is double. Creates no button-press events and adds no dead zone.

Handler parameters
NameTypeDefault
actionNamestring—
valuedouble—
actionName

Internal action name, such as select; not a label or controller-component path.

value

New double value of the Float action.

InputVector2ChangedEvent
# InputVector2Changed
C#
public event XRPositionalTracker.InputVector2ChangedEventHandler InputVector2Changed;

Passes a changed Vector2 value. This event’s parameter is named vector; do not confuse it with value on XRController3D.InputVector2Changed. Applies no normalization or dead zone.

Handler parameters
NameTypeDefault
actionNamestring—
vectorVector2—
actionName

Internal action name, such as select; not a label or controller-component path.

vector

New Vector2 without normalization or a dead zone.

PoseChangedEvent
# PoseChanged
C#
public event XRPositionalTracker.PoseChangedEventHandler PoseChanged;

Passes the shared pose object after every SetPose, even if values are identical. A provider update, not necessarily a coordinate change. Do not dispose or mutate the supplied pose; copy required fields for long-term storage.

Handler parameters
NameTypeDefault
poseXRPose—
pose

Shared pose state. Do not mutate or dispose it; copy required values when retaining data.

PoseLostTrackingEvent
# PoseLostTracking
C#
public event XRPositionalTracker.PoseLostTrackingEventHandler PoseLostTracking;

Passes the retained pose with HasTrackingData already false. Repeated InvalidatePose emits again. Differs from deduplicated TrackingChanged on XREntity3D. Previous coordinates remain available but do not establish a current pose.

Handler parameters
NameTypeDefault
poseXRPose—
pose

Shared pose state. Do not mutate or dispose it; copy required values when retaining data.

ProfileChangedEvent
# ProfileChanged
C#
public event XRPositionalTracker.ProfileChangedEventHandler ProfileChanged;

Emitted when Profile changes. The role parameter actually contains the new profile string, not Left/Right. Repeating the same profile emits nothing.

Handler parameters
NameTypeDefault
rolestring—
role

New profile string; the historical argument name does not mean hand assignment.

XRPositionalTracker.TrackerHand

ValueDescription
Left = 1

This tracker is the left hand controller.

Max = 3

Represents the size of the XRPositionalTracker.TrackerHand enum.

Right = 2

This tracker is the right hand controller.

Unknown = 0

The hand this tracker is held in is unknown or not applicable.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.