namespace Zinnia.Haptics { using UnityEngine; using UnityEngine.XR; /// /// Creates a timed haptic pulse on an . /// public class XRNodeHapticPulser : HapticPulser { [Tooltip("The node to pulse.")] [SerializeField] private XRNode node = XRNode.LeftHand; /// /// The node to pulse. /// public XRNode Node { get { return node; } set { node = value; } } [Tooltip("The duration to pulse Node for.")] [SerializeField] private float duration = 0.005f; /// /// The duration to pulse for. /// /// /// Not supported by all devices. /// public float Duration { get { return duration; } set { duration = value; } } /// /// The haptic capabilities of . /// protected HapticCapabilities nodeHapticCapabilities; /// protected override void DoBegin() { Pulse(Intensity, Duration); } /// protected override void DoCancel() { Pulse(0f, 0f); } /// /// Sends a pulse to . /// /// The intensity to pulse with. /// The duration to pulse for. protected virtual void Pulse(float intensity, float duration) { InputDevice device = InputDevices.GetDeviceAtXRNode(Node); if (!device.TryGetHapticCapabilities(out nodeHapticCapabilities)) { return; } if (nodeHapticCapabilities.supportsImpulse) { device.SendHapticImpulse(0, intensity, duration); } else if (nodeHapticCapabilities.supportsBuffer) { byte[] clip = GeneratePulseBuffer(duration, intensity); device.SendHapticBuffer(0, clip); } } /// /// Generates a pulse buffer array. /// /// The intensity to pulse with. /// The duration to pulse for. /// The buffer array containing the pulse data. protected virtual byte[] GeneratePulseBuffer(float intensity, float duration) { int clipCount = (int)(nodeHapticCapabilities.bufferFrequencyHz * duration); byte[] clip = new byte[clipCount]; for (int index = 0; index < clipCount; index++) { clip[index] = (byte)(byte.MaxValue * intensity); } return clip; } } }