Appearance
Tracking Beta
scene.tracking reads live tracking data from script – articulated hand joints, and face blendshapes when the scene runs in a face context. It is the author-facing entry point for both; you never talk to the underlying provider directly.
Two things it is useful for: reading hand or face data without planting an anchored object, and controlling when the hand-tracking provider is running.
Hands
Hand tracking is currently available on Apple Vision Pro only, and it is opt-in – nothing is tracked until a script asks for it. Gate portable scripts on the feature flag:
javascript
// Attach to: On Experience Start
if (environment.features.has("handTracking")) {
await scene.tracking.hands.enable(); // resolves when tracking is live
}enable() rejects if the device cannot track hands or the person declines permission, so handle the rejection rather than assuming it succeeded:
javascript
// Attach to: On Experience Start
try {
await scene.tracking.hands.enable();
} catch (e) {
console.log("Hand tracking unavailable: " + e.message);
}Once tracking is live, read the hands each frame:
javascript
// Attach to: On Render
var right = scene.tracking.hands.right; // null when that hand isn't tracked
if (right) {
var tip = right.joints.indexFingerTip.worldTransform.position;
console.log("Right index tip: " + tip);
}Hands reference
| Member | Type | Description |
|---|---|---|
enable() | Promise<void> | Opt into hand tracking. Idempotent. Resolves when the provider is running and authorized; rejects if denied or unsupported. |
disable() | – | Drop this script's request. Fire-and-forget. |
isSupported | boolean | Whether this device can track hands at all. |
active | boolean | Whether the provider is authorized and running. |
enabled | boolean | Whether this script currently requests hand tracking. |
left | AnchorData | null | Left hand, or null when it isn't tracked. |
right | AnchorData | null | Right hand, or null when it isn't tracked. |
anchors | Array<AnchorData> | All currently tracked hands. |
active vs enabled vs a hand being visible
These are three different questions – enabled is what your script asked for, active is whether tracking is actually running, and a left / right of null means that particular hand isn't in view right now. Poll active to notice permission being revoked or tracking being lost after a successful enable().
Face
Face data needs no opt-in – it is already flowing whenever the scene runs in a face tracking context, so there is nothing to enable.
javascript
// Attach to: On Render
var face = scene.tracking.face.current;
if (face) {
console.log("Face at: " + face.worldTransform.position);
}Face reference
| Member | Type | Description |
|---|---|---|
isSupported | boolean | Whether the scene can deliver face tracking data. |
active | boolean | Whether a face is currently tracked. |
current | AnchorData | null | The current face anchor – blendshapes and eye transforms – or null. |
Coordinate spaces
Joint and face positions are in world space. To use them against an object you created, convert into that object's local frame first – see Coordinate spaces.
The lower-level equivalent
scene.tracking is a convenience layer over scene.getAnchors(...), which stays available if you would rather filter the anchor list yourself:
javascript
// Attach to: On Render
var anchors = scene.getAnchors("hand");
for (var i = 0; i < anchors.length; i++) {
if (anchors[i].chirality === "right") {
console.log("Right hand at: " + anchors[i].worldTransform.position);
}
}The difference is lifecycle: only scene.tracking.hands can turn the hand-tracking provider on and off. getAnchors("hand") returns an empty list until something has enabled it.
Related
- Anchors – anchoring an object to a hand joint instead of reading joints yourself
- Feature Detection – the full capability matrix
- Examples – worked hand-tracking snippets