Detecting Planes

Detect and interact with real-world planes to create a more immersive AR experience.

Listening for Plane Updates

When calling IARSession.Run(configuration), set the ARConfiguration.PlaneDetection value to specify the types of planes the ARSession should detect.

An ARSession will surface detected planes as ARAnchor objects via events. Each anchor has an AnchorType that will indicate if the anchor is a plane or an image.

session.AnchorsAdded += OnAnchorsAdded;
session.AnchorsUpdated += OnAnchorsUpdated;
session.AnchorsMerged += OnAnchorsMerged;
session.AnchorsRemoved += OnAnchorsRemoved;

So if you want to place a GameObject in the scene where there’s a detected plane anchor:

private readonly Dictionary<Guid, GameObject> planeLookup = new Dictionary<Guid, GameObject>();

private void AnchorsAdded(AnchorsArgs args)
{
 foreach (IARPlaneAnchor anchor in args.Anchors)
 {
   // If the anchor isn't a plane, don't instantiate a GameObject
   if (anchor.AnchorType != AnchorType.Plane)
     continue;

   // Remember this anchor and its GameObject so we can update its position
   // if we receive an update.
   planeLookup.Add(anchor.Identifier, Instantiate(PlanePrefab));
   var gameObject = planeLookup[anchor.Identifier];

   // Display the plane GameObject in the same position, orientation, and scale as the detected plane
   gameObject.transform.position = anchor.Transform.ToPosition();
   gameObject.transform.rotation = anchor.Transform.ToRotation();
   gameObject.transform.localScale = anchor.Extent;
 }
}

void AnchorsUpdated(AnchorsArgs args)
{
  foreach (IARPlaneAnchor anchor in args.Anchors)
  {
    GameObject gameObject;
    if (planeLookup.TryGetValue(anchor.Identifier, out gameObject))
    {
      gameObject.transform.position = anchor.Transform.ToPosition();
      gameObject.transform.rotation = anchor.Transform.ToRotation();
      gameObject.transform.localScale = anchor.Extent;
    }
  }
}

Using ARPlaneManager

To simplify the process of enabling planefinding and visualizing the planes, we provide a Manager you can add to your scene. The API reference and in-code comments/tool tips for ARPlaneManager explains how to use it.

Anchor Merging

When the ARSession realizes that two of the plane anchors it was tracking are actually part of the same larger plane it will merge them, but that merge is handled differently per platform:

Plane Classification (iOS only)

On iPhones XS/XR or newer running iOS 12+ you have the ability to classify planes. That classification is exposed through the anchor’s PlaneClassification. If the plane anchor’s classification is None, the anchor’s PlaneClassificationStatus property gives a reason why the plane couldn’t be classified. Updates to either value are surfaced through the AnchorsUpdated event.

All plane anchors on Android and unsupported iPhones will have a PlaneClassification of None with PlaneClassificationStatus of NotAvailable.