Version: 1.0.2 Target Device: Youbiquo Leonardo XR Base SDK: Snapdragon Spaces 1.0.4
This guide describes how to configure the interaction layer for LeonardoXR applications using standard Unity packages:
| Package | Version | Source |
|---|---|---|
| XR Interaction Toolkit | 3.3.0 | Unity Registry |
| XR Hands | 1.7.2 | Unity Registry |
| AR Foundation | 6.2.1 | Unity Registry |
| Snapdragon Spaces SDK | 1.0.4 | Tarball (Qualcomm) |
| LeonardoXR SDK | 1.0.2 | Tarball (Youbiquo) |
| UniTask | 2.5.10 | Unity Registry |
Note: All dependencies must be installed following the procedure described in Getting Started before proceeding with the interaction configuration.
The package is installed via Window > Package Manager > Unity Registry > XR Interaction Toolkit > Install (version 3.3.0).
If the prompt “Enable the new input system?” appears during installation, click Yes. If the prompt “XR Interaction Layer Mask Update Required” appears, click I Made a Backup, Go Ahead! (for new projects) or No Thanks if a previous version of XRIT was already present.
The Starter Assets include:
After import, an XRI Default Input Actions asset is added to Assets/Samples/XR Interaction Toolkit/[version]/Starter Assets/. This asset is already configured for standard controller profiles (including the Companion Controller via the Microsoft MMRC Profile) and for hands.
To assign the asset to the system:
The minimum hierarchy for an interactive scene on LeonardoXR is:
AR Session
XR Origin (Action-based)
└── Camera Offset
├── Main Camera (tagged "MainCamera")
├── LeftHand Controller
│ ├── XR Ray Interactor (Left)
│ └── XR Direct Interactor (Left)
└── RightHand Controller
├── XR Ray Interactor (Right)
└── XR Direct Interactor (Right)
Create the base structure by selecting GameObject > XR > XR Origin (Action-based) from the main menu.
Warning: Disable the AR Camera Background component — it is not supported on LeonardoXR and will be automatically disabled at runtime. Also disable AR Camera Manager if you are not retrieving RGB frames from the camera.
Add the Input Action Manager component to the XR Origin (or to a persistent GameObject). In the Action Assets field, assign:
XRI Default Input Actions (from the imported Starter Assets).Snapdragon Spaces Input Actions (from Samples/Snapdragon Spaces/[version]/Core Samples/Shared Assets/Input Actions).Leonardo XR’s Companion Controller uses the Microsoft Mixed Reality Motion Controller Profile to send pointing and button inputs from the companion app on your smartphone.
Note: Do not add the Hand Interaction Profile alongside the Companion Controller — it takes precedence and will interfere with controller pointing.
Samples/Snapdragon Spaces/[version]/Core Samples/Shared Assets/Prefabs/Interaction.0.005.Installed via Window > Package Manager > Unity Registry > XR Hands > Install (version 1.7.2).
Warning: The Hand Tracking Subsystem must be enabled in All Features — not only in the Snapdragon Spaces section — to function correctly on LeonardoXR.
Note: Do not add Hand Interaction Profile if you are using the Companion Controller — the two profiles conflict. See the “Combining Controllers and Hand Tracking” section below.
The XR Hands package integrates with the XR Interaction Toolkit via the XR Hand Tracking Events and XR Hand Skeleton Driver components. These components are automatically configured on the XR Origin Controller when using the Starter Assets prefabs from the Hand Interaction Demo.
Recommended hierarchy with XR Hands:
XR Origin (Action-based)
└── Camera Offset
├── Left Hand
│ ├── XR Hand Skeleton Driver
│ ├── XR Hand Mesh Renderer (optional)
│ └── XR Direct Interactor
└── Right Hand
├── XR Hand Skeleton Driver
├── XR Hand Mesh Renderer (optional)
└── XR Ray Interactor (for distance pointing)
using UnityEngine.XR.Hands;
XRHandSubsystem handSubsystem = XRHandSubsystemUtility.GetSubsystem();
if (handSubsystem != null)
{
XRHand leftHand = handSubsystem.leftHand;
if (leftHand.isTracked)
{
if (leftHand.GetJoint(XRHandJointID.IndexTip).TryGetPose(out Pose indexTipPose))
{
// indexTipPose.position = left index tip position
}
}
}
Use the XR Hands Gestures system to detect static or dynamic hand poses:
using UnityEngine.XR.Hands;
// On the scene: add the XRHandGestures component to the XR Origin
// Then subscribe to the events:
[SerializeField] XRHandGestures gestures;
void OnEnable()
{
gestures.gesturePerformed += OnGesturePerformed;
}
void OnGesturePerformed(XRHandGesture gesture, Handedness handedness)
{
Debug.Log($"Gesture: {gesture.gestureName} performed with {handedness}");
}
To make an object selectable by a ray or direct interactor:
// Example: reacting to a select with XR Simple Interactable
using UnityEngine.XR.Interaction.Toolkit;
public class MyButton : MonoBehaviour
{
[SerializeField] XRSimpleInteractable interactable;
void OnEnable()
{
interactable.selectEntered.AddListener(OnSelected);
}
void OnSelected(SelectEnterEventArgs args)
{
Debug.Log("Selected by: " + args.interactorObject);
}
}
XRIT 3.x uses Interaction Layer Masks to filter which interactors can interact with which interactables. Configure the layers via the Inspector or by using:
interactable.interactionLayers = InteractionLayerMask.GetMask("Default", "UI");
For interactive 3D UI on LeonardoXR:
| Parameter | Recommended Value |
|---|---|
| Render Mode | World Space |
| Dynamic Pixels Per Unit | 1 |
| Reference Pixels Per Unit | 100 |
| Scale | 0.001 (for a ~1m canvas = 1000 pixel units) |
On LeonardoXR, it is not possible to simultaneously use the Companion Controller (with raycast) and full Hand Tracking (with raycast from both hands) due to OpenXR profile conflicts.
UniTask 2.5.10 is included as a dependency to handle high-performance asynchronous operations (asset loading, waiting for subsystems, etc.) without GC allocations.
Installed via Window > Package Manager > Unity Registry > UniTask > Install (version 2.5.10), or as a git URL.
using Cysharp.Threading.Tasks;
public class HandSubsystemWaiter : MonoBehaviour
{
async UniTaskVoid Start()
{
// Wait for the XR Hands subsystem to be ready
await UniTask.WaitUntil(() =>
XRHandSubsystemUtility.GetSubsystem()?.running ?? false);
Debug.Log("XR Hands subsystem ready.");
}
}
UniTask is used internally by the LeonardoXR SDK for asynchronous operations. It is recommended to use it in your application code as well to maintain consistency with the SDK lifecycle.
| Profile | Usage |
|---|---|
| Microsoft Mixed Reality Motion Controller Profile | Companion Controller (smartphone as controller) |
| Hand Interaction Profile | Hand tracking with poke/pinch interactors |
Note: The two profiles cannot coexist with raycasting enabled on both. Select one of the options described in the “Combining Controllers and Hand Tracking” section.