Unity MR Part 8: Anchors
Tags: unity3d, mixedreality, tutorial, beginners
Published: 2024-01-11 08:51:08

👀 Stumbled here on accident? Start with the [introduction](https://dev.to/taikonauten/part-0-introduction-56fl)!

📚 This article will guide you through the concept of `Anchors` MR, explaining their significance and functionality. Additionally, it will provide a comprehensive tutorial on implementing `Anchors` within the Unity platform.

---

ℹ️ If you find yourself facing any difficulties, remember that you can always refer to or download the code from our accompanying [GitHub repository](https://github.com/taikonauten/unity-mr-article-series/tree/main/08_Anchors)

---

The aim of this article is to conduct hit tests on planes we created previously, using our controller. We'll then instantiate an Anchor at the identified position. This process is fundamental for accurately positioning virtual objects in relation to the real world.

ℹ️ `Anchors` in MR are virtual reference points that are fixed to a specific location in the real world. They are used to maintain the position and orientation of virtual objects consistently as the user moves around or interacts with the MR environment.

A typical use case for anchors is to place virtual content in the physical world.

---

## AR Anchor Manager component

The `AR Anchor Manager component` creates GameObjects for each anchor and is a critical element for managing AR anchors. It acts as a central point for creating, tracking, and updating anchors in the AR environment. This component is essential for ensuring that virtual objects are anchored accurately to real-world locations, maintaining their position and orientation consistently.

⚠️ Throughout its lifespan, the Meta Quest 3 device usually undertakes extra tasks to keep the anchor's position and orientation up to date. Given that anchors are typically resource-intensive objects, it's advisable to use them wisely.

---

## Adding AR Anchor Manager component to the Scene

In the hierarchy view find the `XR Origin (XR Rig)` GameObject and add the `AR Anchor Manager` script via `Add Component`.


![The XR Origin (XR Rig) GameObject with the added AR Anchor Manager Script](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rl58nbi0ndcctrnc5ios.png)
<figcaption>The XR Origin (XR Rig) GameObject with the added AR Anchor Manager Script</figcaption>
---

There's no need to modify any fields in the `AR Anchor Manager`. The `trackables Changed` is a list of `ARTrackables`, managed by the `ARTrackableManager`. Additionally, the `Anchor Prefab` field is only necessary if there's a requirement to enhance the default Prefab instantiated for each Anchor.

ℹ️ You can read more about the different Managers in `ARFoundation` here: [Managers | AR Foundation | 6.0.0-pre.5.l](https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@6.0/manual/architecture/managers.html).

Let's move on to updating our `MRArticleSeriesController.cs` script. In this update, we'll adjust the script to instantiate an Anchor at the `Pose` of a valid Raycast Hit. For the moment, we'll simply log the creation of the Anchor. In the following article, we will focus on instantiating a Prefab and attaching it to this Anchor.

ℹ️ `Pose` is a representation of a Position, and a Rotation in 3D Space. This structure is used primarily in XR applications to describe the current "pose" of a device in 3D space.

The revised script will be structured as follows:

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.XR.Interaction.Toolkit;

namespace Taikonauten.Unity.ArticleSeries
{
    public class MRArticleSeriesController : MonoBehaviour
    {
        public ActionBasedController controller;
        public InputActionReference buttonAction;
        public XRRayInteractor rayInteractor;
        public ARAnchorManager anchorManager;

        void OnEnable()
        {
            Debug.Log("MRArticleSeriesController -> OnEnable()");
            buttonAction.action.performed += OnButtonPressedAsync;
        }

        void OnDisable()
        {
            Debug.Log("MRArticleSeriesController -> OnDisable()");
            buttonAction.action.performed -= OnButtonPressedAsync;
        }

        private async void OnButtonPressedAsync(InputAction.CallbackContext context)
        {
            Debug.Log("MRArticleSeriesController -> OnButtonPressed()");

            if (rayInteractor.TryGetCurrent3DRaycastHit(out RaycastHit hit))
            {
                Pose pose = new(hit.point, Quaternion.identity);
                Result<ARAnchor> result = await anchorManager.TryAddAnchorAsync(pose);

                result.TryGetResult(out ARAnchor anchor);

                Debug.Log(anchor);
            }
        }
    }
}

```

Before testing the app, it's important to select our `AR Anchor Manager`. To do this, locate the `XR Origin (XR Rig)` GameObject in your hierarchy, and then, as indicated in the following screenshot, choose the `AR Anchor Manager`.


![Selecting the AR Anchor Manager for the MRArticleSeriesController.cs Script](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x9vjx6n4sw9ngzut31jf.png)
<figcaption>Selecting the AR Anchor Manager for the MRArticleSeriesController.cs Script</figcaption>
---

To test the application, choose `Build and Run`, as detailed in the previous articles. Hover over a Plane and press the `Trigger` button. If all configurations are correct, you should see the specified output in your console. Remember to select the correct device, not the Editor, as highlighted in previous articles.


![Console output for the Meta Quest 3 device](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rhptd804roderla0s0p.png)
<figcaption>Console output for the Meta Quest 3 device</figcaption>
---

## Next article

In the upcoming article, we will delve into the process of instantiating a prefab in a MR environment using Unity. This technique is key to bringing virtual objects into your MR space, allowing for a richer and more interactive experience.