using System.Collections; using System.Collections.Generic; using UnityEngine; namespace MoreMountains.NiceVibrations { /// /// A minimal test class you can drop in any scene that can be used to trigger vibrations from its inspector /// public class MMVibrationManagerTester : MonoBehaviour { /// the possible haptic methods for this feedback public enum HapticMethods { NativePreset, Transient, Continuous, AdvancedPattern, Stop } /// the timescale to operate on public enum Timescales { ScaledTime, UnscaledTime } [Header("Haptics")] public HapticMethods HapticMethod = HapticMethods.NativePreset; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.NativePreset)] public HapticTypes HapticType = HapticTypes.None; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.Transient)] public float TransientIntensity = 1f; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.Transient)] public float TransientSharpness = 1f; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)] public float InitialContinuousIntensity = 1f; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)] public AnimationCurve ContinuousIntensityCurve = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1f, 1f)); [MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)] public float InitialContinuousSharpness = 1f; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)] public AnimationCurve ContinuousSharpnessCurve = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1f, 1f)); [MMNVEnumCondition("HapticMethod", (int)HapticMethods.Continuous)] public float ContinuousDuration = 1f; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)] public TextAsset AHAPFileForIOS; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)] public MMNVAndroidWaveFormAsset AndroidWaveFormFile; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)] public MMNVRumbleWaveFormAsset RumbleWaveFormFile; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)] public int AndroidRepeat = -1; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)] public int RumbleRepeat = -1; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)] public HapticTypes OldIOSFallback; [MMNVEnumCondition("HapticMethod", (int)HapticMethods.AdvancedPattern)] public Timescales Timescale = Timescales.UnscaledTime; [Header("Rumble")] public bool AllowRumble = true; [MMNVInspectorButton("TestVibration")] public bool TestVibrationButton; protected static bool _continuousPlaying = false; protected static float _continuousStartedAt = 0f; /// /// When this feedback gets played /// /// /// protected virtual void TestVibration() { Vector3 position = this.transform.position; switch (HapticMethod) { case HapticMethods.AdvancedPattern: string iOSString = (AHAPFileForIOS == null) ? "" : AHAPFileForIOS.text; long[] androidPattern = (AndroidWaveFormFile == null) ? null : AndroidWaveFormFile.WaveForm.Pattern; int[] androidAmplitude = (AndroidWaveFormFile == null) ? null : AndroidWaveFormFile.WaveForm.Amplitudes; long[] rumblePattern = (RumbleWaveFormFile == null) ? null : RumbleWaveFormFile.WaveForm.Pattern; int[] lowFreqAmplitude = (RumbleWaveFormFile == null) ? null : RumbleWaveFormFile.WaveForm.LowFrequencyAmplitudes; int[] highFreqAmplitude = (RumbleWaveFormFile == null) ? null : RumbleWaveFormFile.WaveForm.HighFrequencyAmplitudes; MMVibrationManager.AdvancedHapticPattern(iOSString, androidPattern, androidAmplitude, AndroidRepeat, rumblePattern, lowFreqAmplitude, highFreqAmplitude, RumbleRepeat, OldIOSFallback, this); break; case HapticMethods.Continuous: StartCoroutine(ContinuousHapticsCoroutine()); break; case HapticMethods.NativePreset: MMVibrationManager.Haptic(HapticType, false, AllowRumble, this); break; case HapticMethods.Transient: MMVibrationManager.TransientHaptic(TransientIntensity, TransientSharpness, AllowRumble, this); break; case HapticMethods.Stop: if (_continuousPlaying) { MMVibrationManager.StopContinuousHaptic(AllowRumble); _continuousPlaying = false; } break; } } /// /// A coroutine used to update continuous haptics as they're playing /// /// protected virtual IEnumerator ContinuousHapticsCoroutine() { _continuousStartedAt = (Timescale == Timescales.ScaledTime) ? Time.time : Time.unscaledTime; _continuousPlaying = true; float elapsedTime = ComputeElapsedTime(); MMVibrationManager.ContinuousHaptic(InitialContinuousIntensity, InitialContinuousSharpness, ContinuousDuration, HapticTypes.Success, this); while (_continuousPlaying && (elapsedTime < ContinuousDuration)) { elapsedTime = ComputeElapsedTime(); float remappedTime = Remap(elapsedTime, 0f, ContinuousDuration, 0f, 1f); float intensity = ContinuousIntensityCurve.Evaluate(remappedTime); float sharpness = ContinuousSharpnessCurve.Evaluate(remappedTime); MMVibrationManager.UpdateContinuousHaptic(intensity, sharpness, true); if (AllowRumble) { #if MOREMOUNTAINS_NICEVIBRATIONS_RUMBLE MMNVRumble.RumbleContinuous(intensity, sharpness); #endif } yield return null; } if (_continuousPlaying) { _continuousPlaying = false; MMVibrationManager.StopContinuousHaptic(AllowRumble); } } /// /// This methods computes and returns the elapsed time since the start of the last played continuous haptic /// /// protected virtual float ComputeElapsedTime() { float elapsedTime = (Timescale == Timescales.ScaledTime) ? Time.time - _continuousStartedAt : Time.unscaledTime - _continuousStartedAt; return elapsedTime; } /// /// Remaps value x from AB to CD /// /// /// /// /// /// /// public static float Remap(float x, float A, float B, float C, float D) { float remappedValue = C + (x - A) / (B - A) * (D - C); return remappedValue; } } }