Skip to content

Parent-Child Bodies

Parent-child relationships let you track assemblies where multiple rigid parts are connected. The child body's pose is expressed relative to its parent, and motion constraints limit which degrees of freedom the child can move.

What Are Parent-Child Relationships?

In many real-world scenarios, tracked objects are not independent. A lid sits on a box, a tool is inserted into a holder, or parts of a mechanism move relative to each other. Parent-child relationships model these connections:

  • The parent body is tracked independently in world space
  • The child body's pose is defined relative to the parent
  • Tracked Motion flags limit which degrees of freedom the child body tracks

Use Cases

Scenario Parent Child
Product with lid Box Lid
Tool in holder Holder Tool
Articulated mechanism Base Moving part
Multi-part assembly Main body Sub-component

Setting Up Parent-Child in Unity

1. Create the TrackedBodies

Add a TrackedBody component for each rigid part. Each body needs its own mesh (and a tracking model if using silhouette tracking).

2. Hierarchy

Make the child TrackedBody's GameObject a child of the parent TrackedBody's GameObject in the Unity hierarchy. The parent reference is established through the hierarchy.

3. Configure Tracked Motion

The Tracked Motion setting on the child body controls which degrees of freedom are active relative to the parent. It uses a flags enum:

Flag Description
None Rigidly attached to parent (0 DoF)
Rotation X Can rotate around the local X axis
Rotation Y Can rotate around the local Y axis
Rotation Z Can rotate around the local Z axis
Translation X Can translate along the local X axis
Translation Y Can translate along the local Y axis
Translation Z Can translate along the local Z axis

Combine flags for multi-DoF joints. For example, a hinge allows Rotation Z only. A slider allows Translation X only.

Note

When Tracked Motion is set to None, the child is rigidly fixed to the parent — both bodies move as a single unit. This is useful when you want separate tracking models for different parts of a complex object but they don't move relative to each other.

4. Occlude Parent

Enable Occlude Parent on the child body if the child frequently blocks part of the parent in the camera view. This tells the tracker to account for the child's geometry when tracking the parent.

A Child Is Part of Its Parent

A child body is a part of its parent and never a body of its own. The tracker refines a child inside the solve of its parent only, so the child has no lifecycle of its own.

  • A child is tracked exactly while its parent is tracked, and it stops when its parent stops.
  • A child has no start, stop, re-entry or recovery of its own, and ForceStartTracking() does nothing on a child. The Lifecycle section of the inspector is shown for the parent only.
  • IsTracking and Confidence of a child follow its parent.
  • A child that moves along only some directions of its parent, for example translation X and Z, stays on those directions. XRTracker draws it at the pose its parent is drawn at, moved by the pose the tracker solved for it relative to the parent. While the parent is not tracked, the child stays where its parent carries it.
  • A stationary parent keeps its children with it. When the tracker is given the pose of a stationary parent back, the poses of its children are given back with it.

How It Works

  1. The parent body is tracked normally against the camera image
  2. The child body is solved inside the parent's solve, and only the enabled degrees of freedom are optimized
  3. The constrained axes are held relative to the parent's pose

Example: Box with Lid

Scene Hierarchy:
├── XRTrackerManager
├── Box (TrackedBody)
│   └── Lid (TrackedBody, TrackedMotion = RotationZ)

The lid's TrackedBody has Rotation Z enabled — it can only rotate open and closed relative to the box along one axis.

Assembly Mode (Parts That Are Installed Later)

Assembly mode is for a part that is physically installed during operation. A part with Assembly Mode on is only checked, at the pose its parent gives it, until it attaches. It never pulls the parent before that, even when it has free directions, so a part that is not there cannot drag the parent off.

A part attaches in one of two ways.

Way Description
Confirmation by score (default) The part attaches when its averaged score reaches Quality to Confirm (0.4 by default). From then on it joins the parent's solve.
Attach Manually The part is scored but never joins the parent's solve until your application calls Attach(). It leaves the solve again when your application calls Detach(). Quality to Confirm is not used. IsAttached reads the last request, and a reset of the body does not change it.
var part = GetComponent<TrackedBody>();   // AssemblyMode and AttachManually are on

// The worker has mounted the part
part.Attach();

// The worker has taken the part off
part.Detach();

Free Check

Free Check is for a part with Attach Manually on and no tracked motion. It is off by default. While the part is not attached, it settles its own pose a few millimeters and degrees around its seat on every solve step, from its own evidence only. The parent's solve never includes the part, so the parent never moves for it.

SettledDistance and SettledAngle read how far the part settled. IsInSeat reads false once the part settled farther than Distance Tolerance (0.005 meters by default) or Angle Tolerance (3 degrees by default). Once attached, the part is rigid at its seat again and joins the parent's solve.

Check View and Presence

A part can carry a Check View, which is a transform like the start viewpoint that looks along its forward axis. It is usually a child of the part or of the parent, so it moves with the object. Presence reads Unknown, Present or Absent.

  • Presence judges the part only while the camera is near the check view and still, and only from the evidence of a whole Presence Hold (1 second by default). A step of the hold passes when TrackingQuality reaches the present bar of the method and the part is in its seat.
  • Away from the view, while the camera moves, or before a hold is complete, Presence reads Unknown. A part without a check view always reads Unknown, and TrackingQuality stays the per-frame score.
Setting Default Description
View Distance (m) 0.1 It sets how far the camera may be from the check view and still be near it.
View Angle (deg) 15 It sets how far the camera's viewing direction may turn from the check view's and still be near it.
Stillness Distance (m) 0.015 It sets how far the camera may move over the stillness window and still count as still.
Stillness Angle (deg) 3 It sets how far the camera's viewing direction may turn over the stillness window and still count as still.
Stillness Window (s) 0.5 It sets how long the camera must stay within the stillness bounds to count as still.
Presence Hold (s) 1 It sets how long the evidence of one judgement is gathered.

Existence Check (Is the Child Present?)

A child body's Tracking Quality tells you whether the child is actually where it's expected to be. This acts as a presence or existence check:

  • High quality — the child's mesh matches the image at its expected position relative to the parent. The part is present.
  • Low quality — the image doesn't match what the tracker expects. The part is likely missing, removed, or displaced.

For example, if a lid is expected on a box but has been removed, the lid's tracking quality will drop because the tracker can't find a visual match at that position. Your application can read TrackingQuality on the child body and react accordingly — show a warning, trigger an event, or update UI. Compare it with the bars of the tracking method of the child and never with a fixed number, because the scale of the number depends on the method. The Confidence of the child follows its parent's, so it says nothing about the part itself. For a part in assembly mode, the Presence reading judges the part from a whole hold and is steadier than a single frame.

This is especially useful with Tracked Motion = None (rigidly attached children). The child's position is fully determined by the parent, so tracking quality purely reflects whether the part is visually present at that location.

Tips

  • Start with independent tracking before adding parent-child — verify each body tracks well on its own
  • None motion is useful for complex objects that benefit from separate tracking models for different visual features
  • The parent must be tracked successfully for the child's constraint to be meaningful. If the parent is lost, the child stays where its parent carries it, at its last pose relative to the parent
  • Enable Occlude Parent when the child body frequently overlaps the parent in the camera view