The summary of our problem is that the controller sometimes fails to detect all inputs (specifically from the trigger button, menu button, and trackpad) with the exception of the home button, which still registers.
I understand that in certain environmental conditions, controller tracking is degraded. However, within our Unity application, we do not consider the position or rotation of the controller, only the inputs from the menu button, the trackpad, and the trigger. We would expect similar behavior to the home button if the controller loses tracking–in testing, home button inputs are still received even in those degraded tracking environments. For example, putting the controller in my pocket results in a loss of tracking, but we are still receiving button inputs.
The OS version on our ML2 is 1.12, and the controller version is up to date.
Is the expectation that all button inputs should be working even when controller tracking is lost? I’m trying to determine if this is intended behavior or a bug.
When you are testing whether or not the inputs are working, are you using the input actions directly or reading it directly from the input device in c#?
I wonder if this is a result of the unity input system refusing to read input if the “isTracked” flag is false.
—-
Do you mind trying to get the input based on the following example. Just make sure to change the logic on the bottom by removing the “is tracked” logic.
Tried your suggestion but to no avail, I’ve attached code snippet below.
using CommonCore.Utilities;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.XR;
using InputDevice = UnityEngine.XR.InputDevice;
using XRCommonUsages = UnityEngine.XR.CommonUsages;
namespace ApplicationName
{
public class MagicLeapControllerInput : SingletonBehavior<MagicLeapControllerInput>
{
private readonly StringBuilder _stringBuilder = new StringBuilder();
private InputDevice _trackedDevice;
public Action<Vector3> OnDevicePositionTracked;
public Action<Quaternion> OnDeviceRotationTracked;
public Action<Vector3> OnDeviceVelocityTracked;
public Action<Vector3> OnDeviceAngularVelocityTracked;
public Action<float> OnDeviceTriggerTracked;
public Action<bool> OnDeviceBumperDownTracked;
public Action<bool> OnDeviceMenuDownTracked;
public Action<bool> OnDeviceIsTouchTracked;
public Action<Vector2> OnDeviceTouchPosTracked;
public Vector3 TrackedDevicePosition;
public Quaternion TrackedDeviceRotation;
public Vector3 TrackedDeviceVelocity;
public Vector3 TrackedDeviceAngularVelocity;
public float TrackedDeviceTrigger;
public bool TrackedDeviceBumperDown;
public bool TrackedDeviceMenuDown;
public bool TrackedDeviceIsTouch;
public Vector2 TrackedDeviceTouchPos;
private void Update()
{
_stringBuilder.Clear();
if (GetControllerDevice(ref _trackedDevice))
{
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.devicePosition, out Vector3 devicePosition))
{
TrackedDevicePosition = devicePosition;
OnDevicePositionTracked?.Invoke(devicePosition);
_stringBuilder.AppendLine($"ATTN: Device Position: {devicePosition}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.deviceRotation, out Quaternion deviceRotation))
{
TrackedDeviceRotation = deviceRotation;
OnDeviceRotationTracked?.Invoke(deviceRotation);
_stringBuilder.AppendLine($"ATTN: Device Rotation: {deviceRotation}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.deviceVelocity, out Vector3 deviceVelocity))
{
TrackedDeviceVelocity = deviceVelocity;
OnDeviceVelocityTracked?.Invoke(deviceVelocity);
_stringBuilder.AppendLine($"ATTN: Velocity: {deviceVelocity}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.deviceAngularVelocity, out Vector3 deviceAngularVelocity))
{
TrackedDeviceAngularVelocity = deviceAngularVelocity;
OnDeviceAngularVelocityTracked?.Invoke(deviceAngularVelocity);
_stringBuilder.AppendLine($"ATTN: Angular Velocity: {deviceAngularVelocity}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.trigger, out float deviceTriggerValue))
{
TrackedDeviceTrigger =deviceTriggerValue;
OnDeviceTriggerTracked?.Invoke(deviceTriggerValue);
_stringBuilder.AppendLine($"ATTN: Trigger Value: {deviceTriggerValue}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.gripButton, out bool deviceIsBumperDown))
{
TrackedDeviceBumperDown = deviceIsBumperDown;
OnDeviceBumperDownTracked?.Invoke(deviceIsBumperDown);
_stringBuilder.AppendLine($"ATTN: IsBumperDown: {deviceIsBumperDown}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.menuButton, out bool deviceIsMenuDown))
{
TrackedDeviceMenuDown = deviceIsMenuDown;
OnDeviceMenuDownTracked?.Invoke(deviceIsMenuDown);
_stringBuilder.AppendLine($"ATTN: IsMenuDown: {deviceIsMenuDown}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.primary2DAxisTouch, out bool deviceIsTouchActiveTracked))
{
TrackedDeviceIsTouch = deviceIsTouchActiveTracked;
OnDeviceIsTouchTracked?.Invoke(deviceIsTouchActiveTracked);
_stringBuilder.AppendLine($"ATTN: IsTouchActive: {deviceIsTouchActiveTracked}");
}
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.primary2DAxis, out Vector2 deviceTouchPos))
{
TrackedDeviceTouchPos = deviceTouchPos;
OnDeviceTouchPosTracked?.Invoke(deviceTouchPos);
_stringBuilder.AppendLine($"ATTN: TouchPos: {deviceTouchPos}");
}
//Log the controllers feature values
Debug.Log(_stringBuilder);
}
}
// Checks to see if the referenced Input Device is a tracked Controller.
private bool GetControllerDevice(ref InputDevice controller)
{
_stringBuilder.AppendLine($"ATTN: Curr device is {controller.name}");
if (IsTrackedController(controller))
{
return true;
}
else
{
_stringBuilder.AppendLine($"ATTN: No available device, finding new one");
}
// If we do not have reference to a valid input device or if it is not being tracked search for a new one.
List<InputDevice> devices = new List<InputDevice>();
InputDevices.GetDevicesWithCharacteristics(
InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.HeldInHand, devices);
for (int i = 0; i < devices.Count; i++)
{
if (IsTrackedController(devices[i]))
{
controller = devices[i];
_stringBuilder.AppendLine($"ATTN: Found new input device {controller} {controller.name} {devices[i].characteristics} at index {i}");
return true;
}
}
return true;
}
// Check to see if the controller is valid and tracked.
private bool IsTrackedController(InputDevice controller)
{
// If we have a reference to an input device, make sure that it is tracked.
if (controller.isValid)
{
controller.TryGetFeatureValue(XRCommonUsages.isTracked, out bool tracked);
if (tracked)
{
// If the device is not tracked, search for a new input device.
return true;
}
}
return false;
}
}
}
// Check to see if the controller is valid and tracked.
private bool IsTrackedController(InputDevice controller)
{
// If we have a reference to an input device
return controller.isValid;
}
I just tested it. Sorry - It looks like having the Hand Interaction Profile affects how the controller is registered. I have submitted this to our voice of customer team. For now, you can get around the issue by removing the Hand Interaction Profile from the Input Profiles in the OpenXR settings
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR;
using InputDevice = UnityEngine.XR.InputDevice;
using XRCommonUsages = UnityEngine.XR.CommonUsages;
public class Inputcontrollertester : MonoBehaviour
{
private readonly StringBuilder _stringBuilder = new StringBuilder();
private InputDevice _trackedDevice;
public Text text;
private void Update()
{
List<InputDevice> devices = new List<InputDevice>();
InputDevices.GetDevicesWithCharacteristics(
InputDeviceCharacteristics.Controller | InputDeviceCharacteristics.HeldInHand, devices);
for (int i = 0; i < devices.Count; i++)
{
_trackedDevice = devices[i];
Debug.Log(devices[i].name);
}
if (_trackedDevice.isValid)
{
_stringBuilder.Clear();
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.devicePosition, out Vector3 devicePosition))
_stringBuilder.AppendLine($"Device Position: {devicePosition}");
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.deviceRotation, out Quaternion deviceRotation))
_stringBuilder.AppendLine($"Device Rotation: {deviceRotation}");
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.trigger, out float deviceTriggerValue))
_stringBuilder.AppendLine($"Trigger Value: {deviceTriggerValue}");
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.gripButton, out bool deviceIsBumperDown))
_stringBuilder.AppendLine($"IsBumperDown: {deviceIsBumperDown}");
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.menuButton, out bool deviceIsMenuDown))
_stringBuilder.AppendLine($"IsMenuDown: {deviceIsMenuDown}");
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.primary2DAxisTouch, out bool deviceIsTouchActive))
_stringBuilder.AppendLine($"IsTouchActive: {deviceIsTouchActive}");
//Log the controllers feature values
Debug.Log(_stringBuilder);
text.text = _stringBuilder.ToString();
}
}
}