Haptic controller vibrations are a crucial tool for creating game immersion. While simple "buzzes" (a constant vibration amplitude for a specified duration) can be serviceable, modern controllers allow developers to play custom waveforms through the controllers, such as sawtooth waves, sinewaves, and even Audio Clips. This adds texture and nuance to the effect, and is the superior way to play haptics in 2022.
After much trying, it appears to me that the buffer-based haptics are fully broken for Quest 2 controllers in the Oculus integration for Unity. I have tried in 3 ways:
Using the Unity generic XR system:
byte samples = new byte; // This would be loaded with samples to create a custom vibration waveform var handDevice = InputDevices.GetDeviceAtXRNode(hand == Hand.right ? XRNode.RightHand : XRNode.LeftHand); // Pass the buffer into the controller if its "haptic capabilities" say that it supports buffer-based haptics if (handDevice.TryGetHapticCapabilities(out var capabilities) && capabilities.supportsBuffer) handDevice.SendHapticBuffer(0, samples);
Using Rift S and Quest 1 Touch controllers, the above code runs successfully. Using Quest 2 and Touch 2 controllers, "supportsBuffer" is false on the capabilities class, and the samples cannot be successfully sent. I know that it is incorrect that the Touch 2 controllers do not support the feature, as I have in a few instances been able to send a buffer to Touch 2 controllers using the below method.
var ovrHapticClip = new OVRHapticsClip(myAudioClipToTurnIntoVibration); var channel = OVRHaptics.RightChannel; channel.Queue(ovrHapticClip);
The OVRHaptics class has a function for sending a haptic buffer in through a "channel" (controller). I can actually get this method to work in a test scene. However, it requires me to put the OVR plugin in a legacy setting (Oculus/Tools/OpenXR/Switch to Legacy OVERPlugin (with LibOVR and VRAPI backends) ). If I am not in this setting the function does nothing. In another project, if I set the project to this setting and try to send the haptics buffer, the engine gets stuck in an infinite loop.
According to what I can find online, the OVRHaptics class is intended to be deprecated, anyway, so it doesn't seem like a good solution.
My understanding is that OVRInput is the modern, sanctioned way of sending haptics to Oculus controllers without going through the generic Unity XR system, and they contain a method for a "simple buzz" (amplitude and duration parameters only) via OVRInput.SetControllerVibration. However, they seem to lack any functionality for sending in a custom buffer, unlike the deprecated OVRHaptics.
I would love any advice regarding ways I can get this feature to work. I figure I'm either wrong about some of my conclusions above, or the feature is fully broken at the moment -- either way, I'd love to know. Thanks in advance for your help!