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