122 lines
5.2 KiB
C#
122 lines
5.2 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Common implementation of dual motor rumbling.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This struct is meant for use in devices that implement <see cref="IDualMotorRumble"/>.
|
|
/// </remarks>
|
|
internal struct DualMotorRumble
|
|
{
|
|
/// <summary>
|
|
/// Normalized [0..1] speed of the low-frequency (usually left) motor.
|
|
/// </summary>
|
|
/// <value>Speed of left motor.</value>
|
|
public float lowFrequencyMotorSpeed { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Normalized [0..1] speed of the high-frequency (usually right) motor.
|
|
/// </summary>
|
|
/// <value>Speed of right motor.</value>
|
|
public float highFrequencyMotorSpeed { get; private set; }
|
|
|
|
/// <summary>
|
|
/// Whether either of the motors is currently set to non-zero speeds.
|
|
/// </summary>
|
|
/// <value>True if the motors are currently turned on.</value>
|
|
/// <remarks>
|
|
/// Does not take pausing into account, i.e. <see cref="lowFrequencyMotorSpeed"/> and/or
|
|
/// <see cref="highFrequencyMotorSpeed"/> may be non-zero but haptics on the device
|
|
/// may actually be paused with <see cref="PauseHaptics"/>.
|
|
/// </remarks>
|
|
public bool isRumbling =>
|
|
!Mathf.Approximately(lowFrequencyMotorSpeed, 0f)
|
|
|| !Mathf.Approximately(highFrequencyMotorSpeed, 0f);
|
|
|
|
/// <summary>
|
|
/// Reset motor speeds to zero but retain current values for <see cref="lowFrequencyMotorSpeed"/>
|
|
/// and <see cref="highFrequencyMotorSpeed"/>.
|
|
/// </summary>
|
|
/// <param name="device">Device to send command to.</param>
|
|
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resume haptics by setting motor speeds to the current values of <see cref="lowFrequencyMotorSpeed"/>
|
|
/// and <see cref="highFrequencyMotorSpeed"/>.
|
|
/// </summary>
|
|
/// <param name="device">Device to send command to.</param>
|
|
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
|
public void ResumeHaptics(InputDevice device)
|
|
{
|
|
if (device == null)
|
|
throw new ArgumentNullException("device");
|
|
|
|
if (!isRumbling)
|
|
return;
|
|
|
|
SetMotorSpeeds(device, lowFrequencyMotorSpeed, highFrequencyMotorSpeed);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset haptics by setting both <see cref="lowFrequencyMotorSpeed"/> and <see cref="highFrequencyMotorSpeed"/>
|
|
/// to zero.
|
|
/// </summary>
|
|
/// <param name="device">Device to send command to.</param>
|
|
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
|
public void ResetHaptics(InputDevice device)
|
|
{
|
|
if (device == null)
|
|
throw new ArgumentNullException("device");
|
|
|
|
if (!isRumbling)
|
|
return;
|
|
|
|
SetMotorSpeeds(device, 0.0f, 0.0f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set the speed of the low-frequency (usually left) and high-frequency (usually right) motor
|
|
/// on <paramref name="device"/>. Updates <see cref="lowFrequencyMotorSpeed"/> and
|
|
/// <see cref="highFrequencyMotorSpeed"/>.
|
|
/// </summary>
|
|
/// <param name="device">Device to send command to.</param>
|
|
/// <param name="lowFrequency">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.</param>
|
|
/// <param name="highFrequency">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.</param>
|
|
/// <remarks>
|
|
/// Sends <see cref="DualMotorRumbleCommand"/> to <paramref name="device"/>.
|
|
/// </remarks>
|
|
/// <exception cref="ArgumentNullException"><paramref name="device"/> is null.</exception>
|
|
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);
|
|
}
|
|
}
|
|
}
|