Rotation only tracking on Oculus Quest

Hi,

I’m using the new XR Toolkit on 2019.4.8f. I’ve set up a stationary XR rig with the Tracked Pose Driver set to Rotation only mode. When I move around in the app my controllers get offset by the movement, making them float off in the distance. I assume this offset it applied within the XR Controller class.

Is there a quick fix I could apply?

Solution
Inside the XRController.cs I’ve added a couple of lines of code
0. Add dependency of

using UnityEngine.SpatialTracking;
  1. Make property that will allow you to track the head of the user
private InputDevice m_HeadInputDevice;
....
public InputDevice headInputDevice
        {
            get
            {
                return m_HeadInputDevice.isValid ? m_HeadInputDevice : (m_HeadInputDevice = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye));
            }
        }
  1. Inside the Awake function find and initiate the tracking type
private TrackedPoseDriver.TrackingType m_trackingType;
....
var trackedPoseDriver = FindObjectOfType<TrackedPoseDriver>();
m_trackingType = trackedPoseDriver.trackingType;
  1. Find this line of code
if (inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out devicePosition))
                    transform.localPosition = devicePosition;

and replace it with

if (inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out devicePosition))
                {
                    if (m_trackingType == TrackedPoseDriver.TrackingType.RotationOnly)
                    {
                        if (headInputDevice.TryGetFeatureValue(CommonUsages.centerEyePosition, out centerEyePosition))
                        {
                            transform.localPosition = devicePosition - centerEyePosition;
                        }
                    }
                    else
                    {
                        transform.localPosition = devicePosition;
                    }
                }

This will essentially offset the controller position using the head position.
Update:
Here is a standalone class that you can use instead XRController

public class OculusController : XRController
{
    private InputDevice _headInputDevice;
    private TrackedPoseDriver.TrackingType _trackingType;

    private InputDevice HeadInputDevice
    {
        get
        {
            return _headInputDevice.isValid
                ? _headInputDevice
                : (_headInputDevice = InputDevices.GetDeviceAtXRNode(XRNode.CenterEye));
        }
    }

    private void Start()
    {
        var trackedPoseDriver = FindObjectOfType<TrackedPoseDriver>();
        _trackingType = trackedPoseDriver.trackingType;
    }

    protected override void OnBeforeRender()
    {
        //No way to check if enabled as m_UpdateTrackingType is private
        UpdateTrackingInputOverride();
    }

    private void LateUpdate()
    {
        UpdateTrackingInputOverride();
    }

    private void UpdateTrackingInputOverride()
    {
        if (_trackingType != TrackedPoseDriver.TrackingType.RotationOnly) return;
       
        //Try to get device position
        if (!inputDevice.TryGetFeatureValue(CommonUsages.devicePosition, out var devicePosition)) return;
       
        //Try to get center eye position
        if (HeadInputDevice.TryGetFeatureValue(CommonUsages.centerEyePosition, out var centerEyePosition))
        {
            transform.localPosition = devicePosition - centerEyePosition;
        }
    }
}

Hi! Have you ever encountered the problem of incorrect input of rays? I’m trying to make a proper Ray Interaction with your script. But if I change the position of the head, the ray breaks.