Simple Persistent AR: Setup and SDK implementation

In this first part of the lesson, we cover setting up the Unity project and implementing the SDK with domains.

Project setup

  1. Configure the project for XR development. Go to Edit -> Project Settings -> XR Plug-In Management
    • -> iOS -> enable the Apple ARKit checkbox for iOS devices.
    • -> Android -> enable the ARCore checkbox for Android devices.
  2. Configure build parameters. Go to Project Settings -> Player
    • -> iOS -> Other Settings -> Camera Usage Description and write a camera description, e.g. "Required by AR."
      • On Android, this permission is automatically added to manifest on build. Android will ask for Camera permissions when the app will first run.
    • -> Android -> Other Settings and have
      • Auto Graphics API disabled and OpenGLES3 at the top of the list
      • Scripting backend set to IL2CPP and both ARMv7 and ARM64 selected in Target Architectures
  3. Go to Window -> Package Manager and install the packages listed in Unity & package versions.
  4. In the sample scene, delete the ^Main Camera^.
  5. Create a new ^AR Session^ by selecting GameObject -> XR -> AR Session.
  6. Create a new ^XR Origin^ by selecting GameObject -> XR -> XR Origin (Mobile AR).
  7. In ^XR Origin^, add two components: ^AR Raycast Manager^ and ^AR Plane Manager^.

start-note

We suggest to check which ARFoundation and ARKit/ARCore package versions are installed by Package Manager, as they might not be equal. This is not automatically handled when installing a "Preview" version and mismatch can happen.

end-note

Basic UI

  1. Create a ^Canvas^ by selecting GameObject -> UI -> Canvas.
  2. Inside the canvas, create a ^Button^ element by selecting GameObject -> UI -> Legacy -> Button. Adjust button parameters and text.
  3. Also inside the canvas, create an empty GameObject by selecting GameObject -> Create Empty. This will be used to hold the Calibration UI elements, so we'll call it CalibrateUI.
  4. Inside CalibrateUI, create an ^Image^ element by selecting GameObject -> UI -> Image. Adjust the image parameters and duplicate it so that they cover the top and bottom of the mobile screen, as well as the previously created button.
  5. Create a ^Text^ element by selecting GameObject -> UI -> Legacy -> Text. Add some brief instructions about calibrating using lighthouses.
  6. Create a cube by selecting GameObject -> 3D Object -> Cube. Change the scale of the cube to ^0.2^ so it appears as a 20cm cube in AR. This should be set to inactive so we don't see it until after calibrating into the domain.

ConjureKit and domain implementation

  1. Create a new ^MonoBehaviour^ script named PersistentARinDomain and attach it to an empty GameObject in the scene.
  2. Import ^ConjureKit^ and ^Manna^, as well as the following namespaces: ^UnityEngine.UI^, ^UnityEngine.XR.ARFoundation^, and ^UnityEngine.XR.ARSubsystems^.
using Auki.ConjureKit;
using Auki.ConjureKit.Manna;
using Auki.Integration.ARFoundation;
using UnityEngine.UI;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
  1. Declare a serialized field for the AR Camera:
[SerializeField] private Camera arCamera;
  1. Use strings to store your App Key and App Secret from the Posemesh console. If you don't have these yet, please go back to the Quickstart.
private const string AppKey = "YOUR_APP_KEY";
private const string AppSecret = "YOUR_APP_SECRET";

start-warning

Never share your app secret with anyone.

end-warning

  1. Create private ^IConjureKit^ and ^Manna^ variables.
private IConjureKit _conjureKit;
private Manna _manna;
  1. In the ^Start()^ method, initialize ^ConjureKit^ and ^Manna^ with the app key and secret:
private void Start()
{
    _conjureKit = new ConjureKit(
        arCamera.transform,
        AppKey,
        AppSecret);
    _manna = new Manna(_conjureKit);
    
    var textureProviderComp = CameraFrameProvider.GetOrCreateComponent();
    textureProviderComp.OnNewFrameReady += frame => _manna.ProcessVideoFrameTexture(frame.Texture, frame.ARProjectionMatrix, frame.ARWorldToCameraMatrix);
    _manna.OnLighthouseTracked += OnLighthouseTracked;
    
    _conjureKit.Connect();
}
  1. Declare more serialized fields for the cube and the calibration UI:
[SerializeField] private GameObject cube;
[SerializeField] private GameObject calibrateUI;
  1. Create a private bool variable to store the state of calibration into a posemesh domain:
private bool _calibrated = false;
  1. Define the ^OnLighthouseTracked()^ method used in ^Start()^ to handle the lighthouse tracking event. This method will be called when a lighthouse QR code is tracked by the camera. It will calibrate into the posemesh domain and hide the calibration UI, showing the cube marker instead.
private void OnLighthouseTracked(Lighthouse lighthouse, Pose qrPose, bool isCalibrationGood)
{
    // If the QR detection was good enough and the QR code is static (generated from the posemesh console),
    // hide the calibration view and show the cube marker 
    if (isCalibrationGood && lighthouse.Type == Lighthouse.LighthouseType.Static)
    {
        if(!_calibrated)
        {
            _calibrated = true;
            calibrateUI.SetActive(false);
            cube.SetActive(true);
        }
    }
}

Need a refresher on the essentials?

Check out more lessons, DIY kits and essentials reading material at the developer learning centre homepage.

Want to build on the posemesh and need a helping hand?

Apply for a grant of AUKI tokens to get your project off the ground, and work directly with the Auki Labs team to get your creation to market. Successful applicants may be granted up to 100k USD worth of AUKI tokens, and development and marketing support from the Auki Labs team.