Quick answer: Only treat planes as real when trackingState == TrackingState.Tracking. Use ARAnchors for long-term placements. Smooth pose between updates if jitter persists.
An AR app places a virtual object on a detected table. The object flickers between positions as the plane is refined. Sometimes disappears entirely when tracking is briefly lost.
Filter by Tracking State
void OnPlaneChanged(ARTrackablesChangedEventArgs<ARPlane> args)
{
foreach (var plane in args.added) {
if (plane.trackingState == TrackingState.Tracking) {
ReadyForPlacement(plane);
}
}
}
Skip Limited or None planes. Tracking ones are reliable for placement.
Use ARAnchors for Long-Term
var anchor = anchorManager.AttachAnchor(plane, plane.transform.GetPose());
if (anchor) {
var obj = Instantiate(prefab, anchor.transform);
}
Anchors are AR Foundation’s stable positions; the device’s tracking system continually refines them. Objects attached to anchors stay locked to their real-world location even as the plane representation drifts.
Smooth Pose Between Updates
Pose targetPose = plane.transform.GetPose();
void Update() {
rendered.position = Vector3.Lerp(rendered.position, targetPose.position, Time.deltaTime * 8);
rendered.rotation = Quaternion.Slerp(rendered.rotation, targetPose.rotation, Time.deltaTime * 8);
}
Smoothing factor 8 — tighter is jittery, looser is laggy. Used when plane updates come at lower rate than render.
Plane Visualization Threshold
Add a minimum size threshold before visualizing or treating a plane as valid:
if (plane.size.x < 0.3f || plane.size.y < 0.3f) return; // too small, ignore
Small planes are usually noise from texture detail. Filter them; treats only credibly-tracked surfaces as actionable.
Verifying
Test on a representative surface (wooden table). Plane should appear and stay stable. Lifted in odd angles, tracking state goes Limited; your visualizer should hide. Restored: visualizer reappears smoothly.
“Tracked planes only. Anchor for placement. Smooth for visualization. AR is shaky; your filtering layer is what feels stable to users.”
For demos especially, filter aggressively — players are more forgiving of “loading” than “flicker”.