There are many VR and AR devices on the market today, often operating within their own ecosystems, with their own hardware (hand) controllers and connectable accessories. The unified XR standard that virtual reality companies could follow was missing for a really long time - just the first meaningful proposal - the OpenXR standard - was introduced in the mid of 2019 - after more than 30 years of VR headsets existence. There's a strong name behind the design - the Khronos Group - well known company from the era of wild west on the mobile market. At the turn of milenium, Khronos came with its Open ES and 3D API which helped standardize mobile devices and eliminates software incompatibility. Now it's high time to repeat it in the virtual and augmented reality industry - and because Khronos Group has already gained the support of major players in the field of VR hardware and software development, there's no doubt that wide adoption is on the right track. Do you ask why it's so important? Simply - the main value of the content comes with the possibility of its portability and useability within a variety of devices.
This article deals exclusively with the issue of hardware hand controllers for controlling XR applications. Although controllers from Oculus, HTC, Valve, Google and other manufacturers differ, there are not many differences in the application layer and control logic. How does the support of several controllers is achieved with the help of Input Manager and how many button states the controllers actually have, and possibly how do they differ from each other - it are questions you will get answer for in the following paragraphs ...
Purpose of XR controllers
Hand controller is used to locate the user's hand in space and the possibility of controlling XR (VR and AR) applications. The number of hand controllers is determined by the type of VR headset. Most of the better VR headsets have 2 controllers, where the device for each hand is same - just mirrored (just like the hands). Next change is possible different label of buttons. Basic VR headsets, usually with only 3 degrees of freedom, contain 1 controller only. VR headsets consisting of a mobile phone inserted in a cardboard are basically without a controller, which can be connected to the mobile phone via the bluetooth interface.
Hand controllers are designed with emphasis on ergonomics and simple and intuitive use. They have space just for only a few logically placed buttons of various types which's purpose must be clear even without visual contact during virtual experience.
Buttons on XR controllers
Although the average XR hand controller has only 5 free buttons, it may trigger many states. For example, normal buttons have not only a pressed / unpressed state defined, but also the touch state. For thumbsticks that take a state from 0 to 1 in any direction, there is again touch state + even click state. That's why a developer may track high number of states for controlling an app despite just only 5 physical elements per controller.
Buttons and their properties
- Thumbsticks (2D Axis) - joystick on the joint allowing a deflection of 0 to 1 (compression force) in any free direction. In addition to the vector value of the direction, the joystick also detects touch and click
- Trigger - usually a button on the front of the controller, controlled by the index finger. The output is a compression value from 0 to 1. When the state is higher than a certain defined value, there is trigered also "pressed" state. While there's still value 0, it may be possible to catch "touch" state..
- Grip - Similar to the "Trigger" button, except that the "Grip" is located on the side of the controller, under the middle finger of the hand holding the controller.
- A pair of common buttons - 2 common buttons with states of pressed / not pressed / touched. Buttons on the left controller have usually label X and Y while buttons on the right controller are labeled with letters A and B.
- Touchpad / Trackpad - universal screen capable of detecting touches, swipes and clicks.
- Reserved button -1 button on controllers is usually reserved button of the VR device - e.g. to return back to the menu.
The most used XR hand controllers
This section provides an overview of the most commonly used XR hand controllers. Here you will find 3D models of the controllers (loaded from Sketchfab) with a brief description of their properties and controls. Note that the controls for each driver are more or less different (see the purpose of the XR input manager). If you need the models to load in Unity, you can freely export them from the XR Framework, which I freely made available in section for developers.
Controllers for Oculus Quest / Rift S
Controller for Valve Index
Controllers for HTC Vive
XR input manager
Hand controllers of individual VR headsets differ, not only in number but also in type. This is good to know when designing application controls. In practice, many controls are common, or one element replaces another. Fortunately, the technical aspect of dependencies and the signing of individual buttons usually does not have to be solved - indivual buttons across many VR hand controllers have been mapped and their standardized state is returned by input managers available in an established game engines. The following table is taken from the XR input manager documentation in Unity and shows interconnection of individual buttons across different XR hand controllers. On the application side, only the "InputFeatureUsage" values are worked with, so the only thing that has to be checked is the existence of a button providing the given type of input on the controllers for which the XR application is being developed.
|InputFeatureUsage||Feature type||Legacy input index (left/right controller)||WMR||Oculus||GearVR||Daydream||OpenVR (Full)||Vive||Oculus via OpenVR||WMR via OpenVR||Magic Leap|
|secondary2DAxisClick||Button||[18/19]||Joystick - Click|
|primaryButton||Button||[2/0]||[X/A] - Press||App||Primary||Primary (sandwich button)(1)||Primary (Y/B)||Menu||Menu|
|primaryTouch||Button||[12/10]||[X/A] - Touch|
|secondaryButton||Button||[3/1]||[Y/B] - Press||Alternate||Alternate (X/A)|
|secondaryTouch||Button||[13/11]||[Y/B] - Touch|
|gripButton||Button||[4/5]||Grip - Press||Grip - Press||Grip - Press||Grip - Press||Grip - Press||Grip - Press||Bumper - Press|
|triggerButton||Button||[14/15]||Trigger - Press||Trigger - Press||Trigger - Press||Trigger - Press||Trigger - Press||Trigger - Press||Trigger - Touch||Trigger - Press||Trigger - Press|
|menuButton||Button||[6/7]||Menu||Start (left controller only)|
|primary2DAxisClick||Button||[8/9]||Touchpad - Click||Thumbstick - Press||Touchpad - Press||Touchpad - Press||Trackpad/Joystick - Press||Trackpad - Press||Joystick - Press||Touchpad - Press|
|primary2DAxisTouch||Button||[16/17]||Touchpad - Touch||Thumbstick - Touch||Touchpad - Touch||Touchpad - Touch||Trackpad/Joystick - Touch||Trackpad - Touch||Joystick - Touch||Touchpad - Touch||Touchpad - Touch|
|userPresence||Button||User presence||User presence|
Example of possible states of Oculus Quest controller buttons
The theory is nice, but many things need to be verified in real. It may be done simply by the use of our XR Framework which contains helper function for that. The result of placing one script is visible on the video below - state (value) of all registered buttons is visible on a simple UI.