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