using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace MoreMountains.NiceVibrations
{
public static class MMNVRumble
{
/// whether or not the rumble engine is running right now
public static bool Rumbling = false;
/// whether or not we're playing a continuous rumble right now
public static bool RumblingContinuous = false;
public static Gamepad GetGamepad(int id)
{
if (id != -1)
{
if (id >= Gamepad.all.Count)
{
return Gamepad.current;
}
else
{
return Gamepad.all[id];
}
}
return Gamepad.current;
}
///
/// Rumbles the controller at the specified frequencies for the specified duration
///
/// from 0 to 1
/// from 0 to 1
/// the duration of the rumble, in seconds
/// a monobehaviour to run the coroutine on (usually just use "this")
public static void Rumble(float lowFrequency, float highFrequency, float duration, MonoBehaviour coroutineSupport, int controllerID = -1)
{
coroutineSupport.StartCoroutine(RumbleCoroutine(lowFrequency, highFrequency, duration, controllerID));
}
///
/// A coroutine used to rumble
///
///
///
///
///
private static IEnumerator RumbleCoroutine(float lowFrequency, float highFrequency, float duration, int controllerID = -1)
{
if (GetGamepad(controllerID) == null)
{
yield break;
}
Rumbling = true;
GetGamepad(controllerID).SetMotorSpeeds(lowFrequency, highFrequency);
float startedAt = Time.unscaledTime;
while (Time.unscaledTime - startedAt < duration)
{
yield return null;
}
InputSystem.ResetHaptics();
Rumbling = false;
}
///
/// Requests a rumble for the specified pattern, amplitude and optional repeat
///
/// Pattern.
/// Amplitudes (from 0 to 255).
/// Repeat : -1 : no repeat, 0 : infinite, 1 : repeat once, 2 : repeat twice, etc
public static void Rumble(long[] pattern, int[] amplitudes, int repeat, MonoBehaviour coroutineSupport, int controllerID = -1)
{
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, amplitudes, amplitudes, repeat, coroutineSupport, controllerID));
}
///
/// Requests a rumble for the specified pattern, low and high frequency amplitudes and optional repeat
///
///
///
///
///
///
public static void Rumble(long[] pattern, int[] lowFreqAmplitudes, int[] highFreqAmplitudes, int repeat, MonoBehaviour coroutineSupport, int controllerID = -1)
{
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, lowFreqAmplitudes, highFreqAmplitudes, repeat, coroutineSupport, controllerID));
}
///
/// A coroutine used to play patterns
///
///
///
///
///
///
private static IEnumerator RumblePatternCoroutine(long[] pattern, int[] lowFreqAmplitudes, int[] highFreqAmplitudes, int repeat, MonoBehaviour coroutineSupport, int controllerID = -1)
{
float startedAt = Time.unscaledTime;
float duration = 0f;
for (int i = 0; i < pattern.Length; i++)
{
if (GetGamepad(controllerID) == null)
{
yield break;
}
duration = pattern[i];
startedAt = Time.unscaledTime;
float lowFreqAmplitude = (lowFreqAmplitudes.Length > i) ? lowFreqAmplitudes[i] / 255f : 0f;
float highFreqAmplitude = (highFreqAmplitudes.Length > i) ? highFreqAmplitudes[i] / 255f : 0f;
GetGamepad(controllerID).SetMotorSpeeds(lowFreqAmplitude, highFreqAmplitude);
while (Time.unscaledTime - startedAt < (duration/1000f))
{
yield return null;
}
}
InputSystem.ResetHaptics();
if (repeat == -1)
{
yield break;
}
if (repeat > 1)
{
repeat--;
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, lowFreqAmplitudes, highFreqAmplitudes, repeat, coroutineSupport));
}
if (repeat == 0)
{
coroutineSupport.StartCoroutine(RumblePatternCoroutine(pattern, lowFreqAmplitudes, highFreqAmplitudes, repeat, coroutineSupport));
}
}
///
/// Lets you update rumble values while playing them
///
///
///
public static void RumbleContinuous(float lowFrequency, float highFrequency, int controllerID = -1)
{
if (GetGamepad(controllerID) == null)
{
return;
}
Rumbling = true;
RumblingContinuous = true;
GetGamepad(controllerID).SetMotorSpeeds(lowFrequency, highFrequency);
}
///
/// Stops all rumbles
///
public static void StopRumble()
{
Rumbling = false;
RumblingContinuous = false;
InputSystem.ResetHaptics();
}
///
/// Pauses all rumbles
///
public static void PauseRumble()
{
Rumbling = false;
RumblingContinuous = false;
InputSystem.PauseHaptics();
}
///
/// Resumes all rumbles
///
public static void ResumeRumble()
{
Rumbling = true;
InputSystem.ResumeHaptics();
}
}
}