Simple Shared AR experience: Instant calibration

In this chapter, we'll cover how to use Manna to display and scan a QR code to join a shared AR session.

Adding an entity

Manna module makes it easy to join a session and get instantly calibrated into a shared coordinate system by scanning a Lighthouse (a QR code in this case). Follow these steps to install and use Manna:

1. Open the Package Manager and install the ^Manna^ module.

Manna package

start-note

If you are experiencing issues with Unity editor when installing a new package, try restarting Unity.

end-note

2. Import ^Manna^

using Auki.ConjureKit.Manna;

3. Create a private ^Manna^ variable and initialize it right after ConjureKit

private Manna _manna;
private Manna _manna;

4. Declare a ^Button^ variable that will enable and disable the QR code and a ^bool^ variable to save the QR code visibility state.

[SerializeField] bool qrCodeBool;
[SerializeField] Button qrCodeButton;

5. Toggle the QR code button interactable state in ^ToggleControlsState^ method.

private void ToggleControlsState(bool interactable)
{
    if (spawnButton) spawnButton.interactable = interactable;
    if (qrCodeButton) qrCodeButton.interactable = interactable;
}

6. Add a ^ToggleLighthouse^ method and use _manna.SetLighthouseVisible(true) to show and hide the Lighthouse (QR code).

public void ToggleLighthouse()
{
    qrCodeBool = !qrCodeBool;
    _manna.SetLighthouseVisible(qrCodeBool);
}

7. Feed Manna with AR camera video frames acquired from ARCameraManager to recognize QR codes

start-note

Manna is independent of any specific AR SDK, like ARFoundation. You need to manually choose how to Feed Manna With Video Frames. An example of how to do it in conjunction with ARFoundation can be found in below and in the Manna demo sample.

end-note

private void Update()
{
    FeedMannaWithVideoFrames();
}

private void FeedMannaWithVideoFrames()
{
    var imageAcquired = arCameraManager.TryAcquireLatestCpuImage(out var cpuImage);
    if (!imageAcquired)
    {
        AukiDebug.LogInfo("Couldn't acquire CPU image");
        return;
    }

    if (_videoTexture == null) _videoTexture = new Texture2D(cpuImage.width, cpuImage.height, TextureFormat.R8, false);

    var conversionParams = new XRCpuImage.ConversionParams(cpuImage, TextureFormat.R8);
    cpuImage.ConvertAsync(
        conversionParams,
        (status, @params, buffer) =>
        {
            _videoTexture.SetPixelData(buffer, 0, 0);
            _videoTexture.Apply();
            cpuImage.Dispose();

            _manna.ProcessVideoFrameTexture(
                _videoTexture,
                arCamera.projectionMatrix,
                arCamera.worldToCameraMatrix
            );
        }
    );
}

8. Add a ^Button^ to the scene, configure the on click callback to invoke ^ToggleLighthouse^ method. Drag the button game object to the field you declared in step 5.

9. Subscribe to ^OnEntityAdded^ event to create cubes when other participants add entities in the session.

_conjureKit.OnEntityAdded += CreateCube;

Build to XCode

In File -> Build settings, make sure that you have added open scenes before building to Xcode.

Another Device B running the same app as Device A can now join Device A's Session by scanning the Lighthouse (QR code) of Device A.

Scanning a QR code

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.