docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    Spatial Entities Anchors feature

    Learn how to use anchors with OpenXR Spatial Entities.

    This page is a supplement to the AR Foundation Anchors manual. The following sections only contain information about APIs where OpenXR Spatial Entities exhibit unique platform-specific behavior.

    Tip

    When developing an AR app, refer to both the AR Foundation documentation as well as the required packages for each platform you support.

    Enable Spatial Entities Anchors

    To enable Spatial Entities Anchors in your app:

    1. Go to Project Settings > XR Plug-in Management > OpenXR.
    2. Select either Windows, Mac, Linux settings or Android, Meta Quest, Android XR settings.
    3. Under the OpenXR Feature Groups heading, select the Spatial Entities feature group.
    4. If disabled, enable the Spatial Entities: Anchors OpenXR feature.
    5. Optionally, click the gear icon (⚙) next to Spatial Entities: Anchors to open the Spatial Entities: Anchors window, and configure Spatial Entities Anchors properties.

    Resolve subsystem conflicts

    AR Foundation supports only one enabled anchor provider at a time. If your project also uses other AR Foundation provider plug-ins such as Unity OpenXR: Meta or Unity OpenXR: Android XR, you must disable anchor features among these packages to ensure that only one anchor provider is enabled at a time.

    Refer to the following table to understand the expected behavior of Spatial Entities Anchors relative to other OpenXR-based AR Foundation providers:

    Runtime Behavior of Spatial Entities Anchors feature
    Android XR Parity with Android XR Anchors feature
    Meta Horizon OS Adds support for TryGetSavedAnchorIdsAsync, but has no API for shared anchors

    The Spatial Entities Anchors feature offers a reliable multi-vendor anchors implementation, so Unity generally recommends Spatial Entities for best portability across multiple OpenXR runtimes. However, note that OpenXR doesn't currently have an API for sharing anchors between multiple colocated devices. If your app requires anchor sharing, consider the Meta Quest Anchors feature, which is likely better suited to meet this requirement.

    Feature reference

    Understand the configurable properties of the Spatial Entities Anchors feature.

    Spatial Entities Anchor feature
    Spatial Entities Anchors feature shown in Project Settings.

    The Spatial Entities Anchors feature contains the following configurable properties:

    Property Description
    Automatically Load Saved Anchors If enabled, the Spatial Entities Anchors feature will attempt to load all saved anchors as the runtime is able to track them.

    Permissions

    Your app can't access any spatial data until the user grants the necessary permissions on their device. Refer to Permissions for more information.

    Attach anchors to planes

    For a conceptual explanation of trackable attachments, refer to Trackable attachments in the AR Foundation manual.

    The Spatial Entities provider implements trackable attachments via OpenXR vendor extensions, so trackable attachment support varies per OpenXR runtime. Refer to Anchors platform support for more information about which runtimes support trackable attachments.

    Prerequisites

    Before you attach an anchor to a plane, make sure that the following conditions are in place:

    • The project enables the Spatial Entities: Planes and Spatial Entities: Anchors features in OpenXR Project Settings.
    • The active runtime supports trackable attachments. Check the supportsTrackableAttachments property at runtime to confirm support before you attach an anchor. For more information, refer to Anchors platform support in the AR Foundation manual.
    • The user grants the required scene permissions on the device. Refer to Permissions to learn which permissions each runtime requires.

    Attach an anchor to a plane

    The following example attaches an anchor to a plane using the Spatial Entities provider:

    void AttachAnchorToPlane(ARAnchorManager anchorManager, ARPlane plane, Pose pose)
    {
        // Confirm that the active provider supports trackable attachments before
        // you attempt to attach an anchor. The descriptor is null when no anchor
        // subsystem is running, so use the null-conditional operator to avoid a
        // NullReferenceException.
        if (anchorManager.descriptor?.supportsTrackableAttachments != true)
        {
            Debug.Log("Trackable attachments aren't supported on this runtime.");
            return;
        }
    
        // AttachAnchor routes to the anchor subsystem's TryAttachAnchor implementation,
        // and returns null if the attachment fails.
        var anchor = anchorManager.AttachAnchor(plane, pose);
        if (anchor != null)
            Debug.Log($"Attached an anchor to plane {plane.trackableId}.");
    }
    

    Parent trackable

    When you attach an anchor, the Spatial Entities provider sets the anchor's parentId to the trackable ID of the plane you attached it to. For anchors that aren't attached to a trackable, parentId is TrackableId.invalidId.

    The Spatial Entities provider supports trackable attachments on planes only, and only on runtimes that report the required capabilities.

    Platform-specific success and error codes

    On OpenXR platforms, the XRResultStatus.nativeStatusCode returned by AR Foundation APIs (such as ARAnchorManager.TryAddAnchorAsync) is a wrapper around OpenXR's XrResult.

    You can use the XRResultStatus.nativeStatusCode property to access the underlying XrResult value, as shown in the following example:

    async void AddAnchorAndLogNativeResult(ARAnchorManager mgr)
    {
        // Create an anchor at an arbitrary pose.
        // You could modify this code to use the position of a raycast hit instead.
        var pose = new Pose(Vector3.zero, Quaternion.identity);
        var result = await mgr.TryAddAnchorAsync(pose);
    
        if (result.status.HasNativeStatusCode())
        {
            // To access OpenXR status codes, use the nativeStatusCode property.
            // Cast to XrResult
            var xrResult = (XrResult)result.status.nativeStatusCode;
    
            // Prints the error or success code associated with this operation
            Debug.Log(xrResult);
        }
        else
        {
            // If a native status code isn't present, you don't need to typecast
            // any values to read all debuggable information.
            Debug.Log(result.status);
        }
    }
    
    In This Article
    Back to top
    Copyright © 2026 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)