Skip to main content
Version: 12 Dec 2024

Tracking Origin Example

The Magic Leap Reference Space OpenXR Feature allows developers to change the Tracking Origin Mode. This can be done directly on the XR Origin Component or, for greater flexibility, programmatically.

tip

Some tracking origin options, such as unbounded space, are not visible in the inspector and must be set programmatically. See the Querying Supported Reference Spaces or Using Unbounded Space examples.

Using the XR Origin Componenet

  • Select the XR Origin Componenet in the Inspector
    • Select the XR Origin GameObject in the Hierarchy and find the XR Origin Component in the Inspector. Select the Tracking Origin Mode property. choose one of the three options: Device, Floor, or Unknown.
  • Use a Script
    • You can also change the Tracking Origin Mode programmatically by referencing the XRInputSubsystem.
    • Note that the XRInputSubsystem must be loaded before you can change the Tracking Origin Mode at runtime.

Querying Supported Reference Spaces

caution

This feature requires the OpenXR Magic Leap 2 Reference Space Feature to be enabled in your project's OpenXR Settings (Window > XR Plugin Manager > OpenXR Settings).

This example script changes the reference space at runtime, after ensuring the XRInputSubsystem is loaded. To test this script, add it to a GameObject and assign an input ToggleAction to toggle between the tracking origin modes.

using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR;
using UnityEngine.XR.Management;

public class XRTrackingMode : MonoBehaviour
{
public InputAction ToggleAction;

private XRInputSubsystem _inputSubsystem;

private int _flagIndex = 0;

private readonly TrackingOriginModeFlags[] _supportedFlags =
{ TrackingOriginModeFlags.Device, TrackingOriginModeFlags.Floor, TrackingOriginModeFlags.Unbounded };

IEnumerator Start()
{
yield return new WaitUntil(() => XRGeneralSettings.Instance != null &&
XRGeneralSettings.Instance.Manager != null &&
XRGeneralSettings.Instance.Manager.activeLoader != null &&
XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem<XRInputSubsystem>() != null);

_inputSubsystem = XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem<XRInputSubsystem>();
Debug.Log("Subsystem ready.");

while (enabled)
{
if(ToggleAction.triggered)
{
_flagIndex = _flagIndex > 2 ? 0 : _flagIndex++;
SetSpace(_supportedFlags[_flagIndex]);
}

yield return null;
}
}

public void SetSpace(TrackingOriginModeFlags flag)
{
if (_inputSubsystem.TrySetTrackingOriginMode(flag))
{
Debug.Log("Current Tracking Mode" + _inputSubsystem.GetTrackingOriginMode());
_inputSubsystem.TryRecenter();
}
else
{
Debug.LogError("SetSpace failed to set Tracking Mode Origin to " + flag);
}
}
}

Using Unbounded Space

caution

This feature requires the OpenXR Magic Leap 2 Reference Space Feature to be enabled in your project's OpenXR Settings (Window > XR Plugin Manager > OpenXR Settings).

The Unbounded space tracking origin is not visible in the inspector and must be set programmatically.

his example demonstrates how to set the tracking origin to unbounded via script. This can be useful when using XR MLSDK, where the pose is reported using XR MLSDK while building an application with OpenXR. For instance, if you are using the deprecated ML Camera API, its pose is returned in unbounded space.

using System;
using System.Collections;
using System.Linq;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.XR.Management;
using UnityEngine.XR.OpenXR;
using MagicLeap.OpenXR.Features;

public class ReferenceSpaceToggle : MonoBehaviour
{
private bool inputSubsystemValid;
private XRInputSubsystem inputSubsystem;

// Start is called before the first frame update
IEnumerator Start()
{

var referenceSpaceFeature = OpenXRSettings.Instance.GetFeature<MagicLeapReferenceSpacesFeature>();
if (!referenceSpaceFeature.enabled)
{
Debug.LogError("Unbounded Tracking Space cannot be set if the OpenXR Magic Leap Reference Spaces Feature is not enabled. Stopping Script.");
yield break;
}

yield return new WaitUntil(() => XRGeneralSettings.Instance != null &&
XRGeneralSettings.Instance.Manager != null &&
XRGeneralSettings.Instance.Manager.activeLoader != null &&
XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem<XRInputSubsystem>() != null);

inputSubsystem = XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem<XRInputSubsystem>();
TrackingOriginModeFlags supportedModes = inputSubsystem.GetSupportedTrackingOriginModes();

string supportedSpaces = string.Join("\n",
((TrackingOriginModeFlags[])Enum.GetValues(typeof(TrackingOriginModeFlags))).Where((flag) =>
supportedModes.HasFlag(flag) && flag != TrackingOriginModeFlags.Unknown));
Debug.Log($"Supported Spaces:{supportedSpaces}");

string currentSpace = inputSubsystem.GetTrackingOriginMode().ToString();
Debug.Log($"Current Space:{currentSpace}");

inputSubsystemValid = true;

SetSpace(TrackingOriginModeFlags.Unbounded);
}

public void SetSpace(TrackingOriginModeFlags flag)
{
if (inputSubsystemValid)
{
if (inputSubsystem.TrySetTrackingOriginMode(flag))
{
string currentSpace = inputSubsystem.GetTrackingOriginMode().ToString();
Debug.Log($"Current Space:{currentSpace}");
inputSubsystem.TryRecenter();
return;
}
}
Debug.LogError("SetSpace failed to set Tracking Mode Origin to " + flag.ToString());
}
}