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);
}
}
}