Controller Usage¶
We will introduce the controller usages below including Pose, Button and Others (e.g. battery life, vibration) by using Unity XR, Unity Input System and VIVE Wave™ APIs.
Unity XR features are defined in CommonUsages.
You can read this document to learn the usages of Input System.
VIVE Wave™ XR plugin provides the controller API in the XRSDK package. (refer to Wave XR Plugin Packages).
You can find the controller samples at Assets > Samples > Wave > XR > XR > Controller after imported the Samples from XRSDK package.
Pose¶
For example, you have to access the right controller’s pose.
Unity XR - Pose¶
To apply the right controller’s pose to a GameObject, you will need to add the component Tracked Pose Driver.
To retrieve the right controller’s position in code, we use the CommonUsages.devicePosition in sample code below.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
public const InputDeviceCharacteristics kControllerRightCharacteristics = (
InputDeviceCharacteristics.Right |
InputDeviceCharacteristics.TrackedDevice |
InputDeviceCharacteristics.Controller |
InputDeviceCharacteristics.HeldInHand
);
internal List<InputDevice> m_InputDevices = new List<InputDevice>();
public bool GetRightControllerPosition(out Vector3 position)
{
position = Vector3.zero;
InputDevices.GetDevices(m_InputDevices);
if (m_InputDevices != null && m_InputDevices.Count > 0)
{
for (int i = 0; i < m_InputDevices.Count; i++)
{
// The device is connected.
if (m_InputDevices[i].characteristics.Equals(kControllerRightCharacteristics))
{
if (m_InputDevices[i].TryGetFeatureValue(CommonUsages.isTracked, out bool tracked))
{
if (m_InputDevices[i].TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 value))
{
position = value;
return true;
}
}
}
}
}
return false;
}
Unity Input System - Pose¶
To apply the right controller’s pose to a GameObject, you will need to add the component Tracked Pose Driver (Input System).
To retrieve the right controller’s position in code, we use the InputActionReference Position
and specify the binding path to <XRController>{RightHand}/devicePosition in sample code below.
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
[SerializeField]
private InputActionReference m_Position = null;
public InputActionReference Position { get { return m_Position; } set { m_Position = value; } }
private bool VALIDATE(InputActionReference actionReference, out string msg)
{
msg = "Normal";
if (actionReference == null)
{
msg = "Null reference.";
return false;
}
else if (actionReference.action == null)
{
msg = "Null reference action.";
return false;
}
else if (!actionReference.action.enabled)
{
msg = "Reference action disabled.";
return false;
}
else if (actionReference.action.activeControl == null)
{
msg = "No active control of the reference action, phase: " + actionReference.action.phase;
return false;
}
else if (actionReference.action.controls.Count <= 0)
{
msg = "Action control count is " + actionReference.action.controls.Count;
return false;
}
return true;
}
public bool GetPosition(out Vector3 position, out string msg)
{
position = Vector3.zero;
if (VALIDATE(m_Position, out msg))
{
if (m_Position.action.activeControl.valueType == typeof(Vector3))
position = m_Position.action.ReadValue<Vector3>();
return true;
}
return false;
}
#endif
Wave XR - Pose¶
After imported the XRSDK package, you can find the controller API at Packages > VIVE Wave XR Plugin > Runtime > WaveXRControl.cs.
By using the following code you can retrieve the right controller’s position.
using Wave.OpenXR;
public bool GetRightControllerPosition(out Vector3 position)
{
return InputDeviceControl.GetPosition(InputDeviceControl.ControlDevice.Right, out position);
}
Button¶
For example, you have to access the right controller’s trigger button.
Unity XR - Button¶
About the button usage in Unity XR, please refer to Unity XR Input
Note
Avoid getting XR.InputDevice in MonoBehaviour OnEnable . Instead, we recommend you to get the input devices in Start or through polling in Update if you do NOT have the XR.InputDevice yet.
This is the button mapping table of Wave XR .
Note
The button support depends on the controller hardware. NOT all buttons will be supported in all VIVE Wave™ devices.
E.g. If you use Focus or Focus Plus , you will not get the primaryButton
, primaryTouch
, secondaryButton
and secondaryTouch
events because Focus and Focus Plus do NOT have the A/X and B/Y buttons.
For Vive Focus3 controller attributes, refer to Focus3 Controller Attributes.
Note
The * means the 1st button will be used as default. For example:
- A controller supports the
Touchpad
button only: TheTouchpad
will be used asprimary2DAxis
. - A controller supports the
Thumbstick
button only: TheThumbstick
will be used asprimary2DAxis
. - A controller supports both the
Touchpad
andThumbstick
buttons: TheTouchpad
will be used asprimary2DAxis
.
Note
The Thumbstick is as known as Joystick.
To retrieve the right controller’s trigger button in code, we use the CommonUsages.triggerButton in sample code below.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
public const InputDeviceCharacteristics kControllerRightCharacteristics = (
InputDeviceCharacteristics.Right |
InputDeviceCharacteristics.TrackedDevice |
InputDeviceCharacteristics.Controller |
InputDeviceCharacteristics.HeldInHand
);
internal List<InputDevice> m_InputDevices = new List<InputDevice>();
public bool GetRightControllerTriggerButton(out bool pressed)
{
pressed = false;
InputDevices.GetDevices(m_InputDevices);
if (m_InputDevices != null && m_InputDevices.Count > 0)
{
for (int i = 0; i < m_InputDevices.Count; i++)
{
// The device is connected.
if (m_InputDevices[i].characteristics.Equals(kControllerRightCharacteristics))
{
if (m_InputDevices[i].TryGetFeatureValue(CommonUsages.triggerButton, out bool value))
{
pressed = value;
return true;
}
}
}
}
return false;
}
Unity Input System - Button¶
To retrieve the right controller’s trigger button in code, we use the InputActionReference ActionReference
and specify the binding path to <XRController>{RightHand}/{triggerButton} in sample code below.
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
[SerializeField]
private InputActionReference m_ActionReference;
public InputActionReference ActionReference { get => m_ActionReference ; set => m_ActionReference = value; }
private bool VALIDATE(InputActionReference actionReference, out string msg)
{
msg = "Normal";
if (actionReference == null)
{
msg = "Null reference.";
return false;
}
else if (actionReference.action == null)
{
msg = "Null reference action.";
return false;
}
else if (!actionReference.action.enabled)
{
msg = "Reference action disabled.";
return false;
}
else if (actionReference.action.activeControl == null)
{
msg = "No active control of the reference action, phase: " + actionReference.action.phase;
return false;
}
else if (actionReference.action.controls.Count <= 0)
{
msg = "Action control count is " + actionReference.action.controls.Count;
return false;
}
return true;
}
public bool GetButton(out bool value, out string msg)
{
value = false;
if (VALIDATE(m_ActionReference, out msg))
{
if (m_ActionReference.action.activeControl.valueType == typeof(float))
value = m_ActionReference.action.ReadValue<float>() > 0;
if (m_ActionReference.action.activeControl.valueType == typeof(bool))
value = m_ActionReference.action.ReadValue<bool>();
return true;
}
return false;
}
Wave XR - Button¶
After imported the XRSDK package, you can find the controller API at Packages > VIVE Wave XR Plugin > Runtime > WaveXRControl.cs.
By using the following code you can retrieve the right controller’s trigger button.
using Wave.OpenXR;
public bool IsRightControllerTriggerButtonPressed()
{
return InputDeviceControl.KeyDown(InputDeviceControl.ControlDevice.Right, CommonUsages.triggerButton);
}
Unity Input Helper¶
Unity XR provides an additional feature package named XR Interaction Toolkit which can be imported from the Window > Package Manager.
After imported the XR Interaction Toolkit package, you can use the InputHelper to retrieve the button state.
For example, you will get a pressed state when you touch the Focus Plus touchpad up with the axis value [0, 1] bigger than 0.7 by using the following code.
using UnityEngine.XR;
void Update()
{
bool touchpad_Y_pressed = false;
if (InputHelpers.IsPressed(InputDevices.GetDeviceAtXRNode(XRNode.RightHand), InputHelpers.Button.PrimaryAxis2DUp, out bool value, .7f))
{
// True if right touchpad Y axis > 0.7
touchpad_Y_pressed = value;
}
}
Others¶
Battery Life¶
For example, you have to retrieve the right controller’s battery life.
Unity XR: Use CommonUsages.batteryLevel.
Unity Input System: Use <XRController>{RightHand}/batteryLevel.
Wave XR: Use
InputDeviceControl.GetBatteryLevel
.
Vibration¶
For example, you have to vibrate the right controller.
- Unity XR: Sample code as below.
using UnityEngine.XR;
using System.Collections.Generic;
public const InputDeviceCharacteristics kControllerRightCharacteristics = (
InputDeviceCharacteristics.Right |
InputDeviceCharacteristics.TrackedDevice |
InputDeviceCharacteristics.Controller |
InputDeviceCharacteristics.HeldInHand
);
internal List<InputDevice> m_InputDevices = new List<InputDevice>();
public bool VibrateRightController(float amplitude, float duration)
{
InputDevices.GetDevices(m_InputDevices);
if (m_InputDevices != null && m_InputDevices.Count > 0)
{
for (int i = 0; i < m_InputDevices.Count; i++)
{
// The device is connected.
if (m_InputDevices[i].characteristics.Equals(kControllerRightCharacteristics))
{
if (m_InputDevices[i].TryGetHapticCapabilities(out HapticCapabilities value))
{
if (value.supportsImpulse)
{
amplitude = Mathf.Clamp(amplitude, 0, 1);
return m_InputDevices[i].SendHapticImpulse(0, amplitude, duration);
}
}
}
}
}
return false;
}
- Unity Input System: Sample code as below.
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.XR;
public InputActionReference action;
public float _amplitude = 1.0f;
public float _duration = 0.1f;
private void Start()
{
if (action == null)
return;
action.action.Enable();
action.action.performed += (ctx) =>
{
var control = action.action.activeControl;
if (null == control)
return;
if (control.device is XRControllerWithRumble rumble)
rumble.SendImpulse(_amplitude, _duration);
};
}
- Wave XR: Use
InputDeviceControl.SendHapticImpulse
.