using System; using UnityEngine.InputSystem.LowLevel; ////REVIEW: should we keep an explicit playback status? ATM calling ResumeHaptics() will re-issue last set motor speed regardless of pause state namespace UnityEngine.InputSystem.Haptics { /// /// Common implementation of dual motor rumbling. /// /// /// This struct is meant for use in devices that implement . /// internal struct DualMotorRumble { /// /// Normalized [0..1] speed of the low-frequency (usually left) motor. /// /// Speed of left motor. public float lowFrequencyMotorSpeed { get; private set; } /// /// Normalized [0..1] speed of the high-frequency (usually right) motor. /// /// Speed of right motor. public float highFrequencyMotorSpeed { get; private set; } /// /// Whether either of the motors is currently set to non-zero speeds. /// /// True if the motors are currently turned on. /// /// Does not take pausing into account, i.e. and/or /// may be non-zero but haptics on the device /// may actually be paused with . /// public bool isRumbling => !Mathf.Approximately(lowFrequencyMotorSpeed, 0f) || !Mathf.Approximately(highFrequencyMotorSpeed, 0f); /// /// Reset motor speeds to zero but retain current values for /// and . /// /// Device to send command to. /// is null. public void PauseHaptics(InputDevice device) { if (device == null) throw new ArgumentNullException("device"); if (!isRumbling) return; var command = DualMotorRumbleCommand.Create(0f, 0f); device.ExecuteCommand(ref command); } /// /// Resume haptics by setting motor speeds to the current values of /// and . /// /// Device to send command to. /// is null. public void ResumeHaptics(InputDevice device) { if (device == null) throw new ArgumentNullException("device"); if (!isRumbling) return; SetMotorSpeeds(device, lowFrequencyMotorSpeed, highFrequencyMotorSpeed); } /// /// Reset haptics by setting both and /// to zero. /// /// Device to send command to. /// is null. public void ResetHaptics(InputDevice device) { if (device == null) throw new ArgumentNullException("device"); if (!isRumbling) return; SetMotorSpeeds(device, 0.0f, 0.0f); } /// /// Set the speed of the low-frequency (usually left) and high-frequency (usually right) motor /// on . Updates and /// . /// /// Device to send command to. /// Speed of the low-frequency (left) motor. Normalized [0..1] value /// with 1 indicating maximum speed and 0 indicating the motor is turned off. Will automatically /// be clamped into range. /// Speed of the high-frequency (right) motor. Normalized [0..1] value /// with 1 indicating maximum speed and 0 indicating the motor is turned off. Will automatically /// be clamped into range. /// /// Sends to . /// /// is null. public void SetMotorSpeeds(InputDevice device, float lowFrequency, float highFrequency) { if (device == null) throw new ArgumentNullException("device"); lowFrequencyMotorSpeed = Mathf.Clamp(lowFrequency, 0.0f, 1.0f); highFrequencyMotorSpeed = Mathf.Clamp(highFrequency, 0.0f, 1.0f); var command = DualMotorRumbleCommand.Create(lowFrequencyMotorSpeed, highFrequencyMotorSpeed); device.ExecuteCommand(ref command); } } }