Input Device Feature Values
It is recommended that developers read the controller input using Unity's Input System. However, developers can obtain the controller's input directly from the InputDevice
. This section provides an example of reading input using the TryGetFeatureValue
method and XRCommonUsages
features.
caution
This feature requires the HAND_TRACKING
permission to be enabled in your project's Permissions Settings (Edit > Project Settings > Magic Leap > Permissions).
Example
This example script finds a connected controller if one is present and logs the input values using the TryGetFeatureValue()
method and XRCommonUsages
.
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.XR;
using InputDevice = UnityEngine.XR.InputDevice;
using XRCommonUsages = UnityEngine.XR.CommonUsages;
/// <summary>
/// This script finds a connected controller and logs the input values using the TryGetFeatureValue method and XRCommonUsages.
/// </summary>
public class ControllerInputExample : MonoBehaviour
{
private readonly StringBuilder _stringBuilder = new StringBuilder();
private InputDevice _trackedDevice;
private void Update()
{
if (GetControllerDevice(ref _trackedDevice))
{
_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.deviceVelocity, out Vector3 deviceVelocity))
_stringBuilder.AppendLine($"Velocity: {deviceVelocity}");
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.deviceAngularVelocity, out Vector3 deviceAngularVelocity))
_stringBuilder.AppendLine($"Angular Velocity: {deviceAngularVelocity}");
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}");
if (_trackedDevice.TryGetFeatureValue(XRCommonUsages.primary2DAxis, out Vector2 deviceTouchPos))
_stringBuilder.AppendLine($"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)
{
if(IsTrackedController(controller)){
return true;
}
// 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]))
{
Debug.Log($"device {i}: {devices[i].characteristics} [isTracked: {tracked}]");
controller = devices[i];
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, 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;
}
}