9 internal static class UnityXRHapticAbstraction
12 internal static void VibrateBoth(
float seconds,
double[] amplitude)
14 seconds = UnityEngine.Mathf.Max(UnityEngine.Time.fixedDeltaTime, seconds);
15 System.Collections.Generic.List<UnityEngine.XR.XRNodeState> nodeStates =
new System.Collections.Generic.List<UnityEngine.XR.XRNodeState>();
16 UnityEngine.XR.InputTracking.GetNodeStates(nodeStates);
17 foreach (UnityEngine.XR.XRNodeState nodeState in nodeStates)
19 if (nodeState.nodeType == UnityEngine.XR.XRNode.LeftHand)
21 VibrateLeft(seconds, amplitude);
23 else if (nodeState.nodeType == UnityEngine.XR.XRNode.RightHand)
25 VibrateRight(seconds, amplitude);
30 internal static bool VibrateLeft(
float seconds,
double[] amplitude)
32 seconds = UnityEngine.Mathf.Max(UnityEngine.Time.fixedDeltaTime, seconds);
33 return VibrateXRNode(seconds, UnityEngine.XR.XRNode.LeftHand, amplitude);
36 internal static bool VibrateRight(
float seconds,
double[] amplitude)
38 seconds = UnityEngine.Mathf.Max(UnityEngine.Time.fixedDeltaTime, seconds);
39 return VibrateXRNode(seconds, UnityEngine.XR.XRNode.RightHand, amplitude);
49 internal static bool VibrateXRNode(
float seconds, UnityEngine.XR.XRNode node,
double[] amplitude)
51 UnityEngine.XR.HapticCapabilities caps =
new UnityEngine.XR.HapticCapabilities();
52 if (!UnityEngine.XR.InputDevices.GetDeviceAtXRNode(node).TryGetHapticCapabilities(out caps))
54 UnityEngine.Debug.LogWarning(
"HAR ERROR!: " + node.ToString() +
" doesn't support haptic feedback or not connected to your system!");
58 if (caps.supportsBuffer)
61#if UNITY_EDITOR||UNITY_STANDALONE_WIN
62 return UnityEngine.XR.InputDevices.GetDeviceAtXRNode(node).SendHapticImpulse(0, (
float)PulseFromBuffer(amplitude), seconds);
64 return GenerateHapticClip(seconds, node, ref clip, amplitude) ? UnityEngine.XR.InputDevices.GetDeviceAtXRNode(node).SendHapticBuffer(0, clip) :
false;
67 else if (caps.supportsImpulse)
69 return UnityEngine.XR.InputDevices.GetDeviceAtXRNode(node).SendHapticImpulse(0, (
float)PulseFromBuffer(amplitude), seconds);
73 UnityEngine.Debug.LogWarning(
"HAR ERROR!: " + node.ToString() +
" doesn't support buffer or impulse!");
78 internal static double PulseFromBuffer(
double[] _buffer)
80 if ((_buffer ==
null) || (_buffer.Length == 0))
86 for (
int i = 0; i < _buffer.Length; i++)
91 return UnityEngine.Mathf.Clamp((
float)(result / _buffer.Length), 0, 1);
96 internal static bool GenerateHapticClip(
float seconds, UnityEngine.XR.XRNode node, ref
byte[] clip,
double[] amplitudes)
98 UnityEngine.XR.HapticCapabilities caps =
new UnityEngine.XR.HapticCapabilities();
100 if (!UnityEngine.XR.InputDevices.GetDeviceAtXRNode(node).TryGetHapticCapabilities(out caps))
106 int clipCount = (int)((
double)caps.bufferFrequencyHz * seconds);
107 clip =
new byte[clipCount];
109 if (clip.Length <= 0)
114 if (clip.Length == 1)
116 clip[0] = (byte)(PulseFromBuffer(amplitudes) * (double)
byte.MaxValue);
124 for (i = 0, j = 0; UnityEngine.Mathf.CeilToInt((
float)i) < amplitudes.Length && j < clip.Length; i += (amplitudes.Length - 1.0f) / (clip.Length - 1.0f), j++)
126 double a = amplitudes[UnityEngine.Mathf.FloorToInt((
float)i)]
127 + (j * (amplitudes.Length - 1.0f) / (clip.Length - 1.0f) - UnityEngine.Mathf.FloorToInt((
float)i))
128 * (amplitudes[UnityEngine.Mathf.CeilToInt((
float)i)] - amplitudes[UnityEngine.Mathf.FloorToInt((
float)i)]);
129 clip[j] = (byte)(a * (
double)
byte.MaxValue);