UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

architecture

[Meta OpenXR] Fix Quest 3 Hand Tracking Disconnect When Using Controllers

Solution

networkinginputopenxrXRcontrollers

Unity 2022.3.x - Unity 6.3.x

Published 18 days ago

Issue

 XR Hand tracking ceases immediately when a Quest 3 Controller is active or held. This occurs despite having XR Hands and Meta OpenXR features installed, preventing hybrid input scenarios where both controllers and hands are required simultaneously.

Ensure the XRLoader remains active at startup and enable the Simultaneous Hands and Controllers feature within the Meta OpenXR settings.

Explanation

The root cause is typically associated with the lifecycle management of XRSubsystem instances or the default exclusive input mode of the Meta OpenXR provider. If your script manually interferes with the XRLoader, hand tracking providers often fail to restart correctly when controllers are present.

To ensure consistent behavior, the XRLoader must remain operational from the application launch. Furthermore, the Meta Quest runtime requires an explicit feature flag to be enabled for concurrent input.

  1. Open Project Settings > XR Plug-in Management > OpenXR.
  2. In the Features tab (Android icon), locate the Meta Quest Feature list.
  3. Enable the Hand Tracking feature and the Meta Quest Support feature group.
  4. Locate the Simultaneous Hands and Controllers checkbox and ensure it is enabled to allow both input types.
  5. Verify that your script does not call StopSubsystems() on the XRLoader during the initial Awake or Start phase.

Additional Tips:

  • Check that the AndroidManifest.xml includes the com.oculus.permission.HAND_TRACKING permission to prevent system-level blocking.
  • Ensure the XRHandSubsystem is being correctly retrieved from the XRLoader if you are performing manual lifecycle checks.
  • For Unity 6, verify that the Meta XR SDK version is 65.0 or higher to support the latest SHAC (Simultaneous Hands and Controllers) features.

Copy


using UnityEngine;
using UnityEngine.XR.Management;
using UnityEngine.XR.Hands;

public class XRInputLifecycleManager : MonoBehaviour
{
    private void Start()
    {
        // Ensure the loader is running and manually start the hand subsystem if it failed to initialize
        if (XRGeneralSettings.Instance.Manager.activeLoader != null)
        {
            var handSubsystem = XRGeneralSettings.Instance.Manager.activeLoader.GetLoadedSubsystem<XRHandSubsystem>();
            if (handSubsystem != null && !handSubsystem.running)
            {
                handSubsystem.Start();
            }
        }
    }
}

Related Posts Haven't quite found a solution to your problem? We think these posts might help you.

Content inspired by a Unity discussion post.