using UnityEngine; using System.Collections; using MoreMountains.Feedbacks; #if MOREMOUNTAINS_NICEVIBRATIONS_INSTALLED using Lofelt.NiceVibrations; #endif namespace MoreMountains.FeedbacksForThirdParty { /// /// Add this feedback to play a continuous haptic of the specified amplitude and frequency over a certain duration. This feedback will also let you randomize these, and modulate them over time. /// [AddComponentMenu("")] #if MOREMOUNTAINS_NICEVIBRATIONS_INSTALLED [FeedbackPath("Haptics/Haptic Continuous")] #endif [FeedbackHelp("Add this feedback to play a continuous haptic of the specified amplitude and frequency over a certain duration. This feedback will also let you randomize these, and modulate them over time.")] public class MMF_NVContinuous : MMF_Feedback { #if MOREMOUNTAINS_NICEVIBRATIONS_INSTALLED /// a static bool used to disable all feedbacks of this type at once public static bool FeedbackTypeAuthorized = true; #if UNITY_EDITOR public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.HapticsColor; } } #endif public override float FeedbackDuration { get { return ApplyTimeMultiplier(_duration); } set { _duration = value; } } [MMFInspectorGroup("Haptic Amplitude", true, 31)] /// the minimum amplitude at which this clip should play (amplitude will be randomized between MinAmplitude and MaxAmplitude) [Tooltip("the minimum amplitude at which this clip should play (amplitude will be randomized between MinAmplitude and MaxAmplitude)")] [Range(0f, 1f)] public float MinAmplitude = 1f; /// the maximum amplitude at which this clip should play (amplitude will be randomized between MinAmplitude and MaxAmplitude) [Tooltip("the maximum amplitude at which this clip should play (amplitude will be randomized between MinAmplitude and MaxAmplitude)")] [Range(0f, 1f)] public float MaxAmplitude = 1f; [MMFInspectorGroup("Haptic Frequency", true, 32)] /// the minimum frequency at which this clip should play (frequency will be randomized between MinFrequency and MaxFrequency) [Tooltip("the minimum frequency at which this clip should play (frequency will be randomized between MinFrequency and MaxFrequency)")] [Range(0f, 1f)] public float MinFrequency = 1f; /// the maximum frequency at which this clip should play (frequency will be randomized between MinFrequency and MaxFrequency) [Tooltip("the maximum frequency at which this clip should play (frequency will be randomized between MinFrequency and MaxFrequency)")] [Range(0f, 1f)] public float MaxFrequency = 1f; [MMFInspectorGroup("Duration", true, 33)] /// the minimum duration at which this clip should play (duration will be randomized between MinDuration and MaxDuration) [Tooltip("the minimum duration at which this clip should play (duration will be randomized between MinDuration and MaxDuration)")] public float MinDuration = 1f; /// the maximum duration at which this clip should play (duration will be randomized between MinDuration and MaxDuration) [Tooltip("the maximum duration at which this clip should play (duration will be randomized between MinDuration and MaxDuration)")] public float MaxDuration = 1f; [MMFInspectorGroup("Real-time Modulation", true, 34)] /// whether or not to modulate the haptic signal at runtime [Tooltip("whether or not to modulate the haptic signal at runtime")] public bool UseRealTimeModulation = false; /// if UseRealTimeModulation:true, the curve along which to modulate amplitude for this continuous haptic, over its total duration [Tooltip("if UseRealTimeModulation:true, the curve along which to modulate amplitude for this continuous haptic, over its total duration")] [MMFCondition("UseRealTimeModulation", true)] public AnimationCurve AmplitudeMultiplication = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1f), new Keyframe(1, 0f)); /// if UseRealTimeModulation:true, the curve along which to modulate frequency for this continuous haptic, over its total duration [Tooltip("if UseRealTimeModulation:true, the curve along which to modulate frequency for this continuous haptic, over its total duration")] [MMFCondition("UseRealTimeModulation", true)] public AnimationCurve ShiftFrequency = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1f), new Keyframe(1, 0f)); [MMFInspectorGroup("Settings", true, 16)] /// a set of settings you can tweak to specify how and when exactly this haptic should play [Tooltip("a set of settings you can tweak to specify how and when exactly this haptic should play")] public MMFeedbackNVSettings HapticSettings; protected Coroutine _coroutine; protected float _duration = 0f; /// /// On play we randomize our amplitude and frequency, trigger our haptic, and initialize real time modulation if needed /// /// /// protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f) { if (!Active || !FeedbackTypeAuthorized || !HapticSettings.CanPlay()) { return; } float amplitude = Random.Range(MinAmplitude, MaxAmplitude); float frequency = Random.Range(MinFrequency, MaxFrequency); _duration = Random.Range(MinDuration, MaxDuration); HapticSettings.SetGamepad(); HapticPatterns.PlayConstant(amplitude, frequency, FeedbackDuration); if (UseRealTimeModulation) { _coroutine = Owner.StartCoroutine(RealtimeModulationCo()); } } /// /// A coroutine used to modulate frequency and amplitude at runtime /// /// protected virtual IEnumerator RealtimeModulationCo() { IsPlaying = true; float journey = NormalPlayDirection ? 0f : FeedbackDuration; while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0)) { float remappedTime = MMFeedbacksHelpers.Remap(journey, 0f, FeedbackDuration, 0f, 1f); HapticController.clipLevel = AmplitudeMultiplication.Evaluate(remappedTime); HapticController.clipFrequencyShift = ShiftFrequency.Evaluate(remappedTime); journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime; yield return null; } HapticController.clipLevel = AmplitudeMultiplication.Evaluate(FinalNormalizedTime); HapticController.clipFrequencyShift = ShiftFrequency.Evaluate(FinalNormalizedTime); IsPlaying = false; _coroutine = null; yield return null; } /// /// On stop we stop haptics and our coroutine /// /// /// protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1) { if (!FeedbackTypeAuthorized) { return; } base.CustomStopFeedback(position, feedbacksIntensity); IsPlaying = false; HapticController.Stop(); if (Active && (_coroutine != null)) { Owner.StopCoroutine(_coroutine); _coroutine = null; } } #else protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f) { } #endif } }