using UnityEngine; using MoreMountains.Feedbacks; using MoreMountains.Tools; using UnityEngine.Rendering; using SLSFramework.Rendering.PostProcessing; namespace MoreMountains.FeedbacksForThirdParty { public struct MMStrobeFlashShakeEvent { public static void Register(Delegate callback) { OnEvent += callback; } public static void Unregister(Delegate callback) { OnEvent -= callback; } public delegate void Delegate(MMF_Feedback source, float duration, float feedbacksIntensity = 1.0f, MMChannelData channelData = null, bool resetShakerValuesAfterShake = true, bool resetTargetValuesAfterShake = true, bool forwardDirection = true, TimescaleModes timescaleMode = TimescaleModes.Scaled, bool stop = false, bool restore = false, bool modifyExtra = false, float frequency = 15f, Color colorHigh = default, Color colorLow = default); public static event Delegate OnEvent; public static void Trigger(MMF_Feedback source, float duration, float feedbacksIntensity = 1.0f, MMChannelData channelData = null, bool resetShakerValuesAfterShake = true, bool resetTargetValuesAfterShake = true, bool forwardDirection = true, TimescaleModes timescaleMode = TimescaleModes.Scaled, bool stop = false, bool restore = false, bool modifyExtra = false, float frequency = 15f, Color colorHigh = default, Color colorLow = default) { OnEvent?.Invoke(source, duration, feedbacksIntensity, channelData, resetShakerValuesAfterShake, resetTargetValuesAfterShake, forwardDirection, timescaleMode, stop, restore, modifyExtra, frequency, colorHigh, colorLow); } } [AddComponentMenu("More Mountains/Feedbacks/Shakers/PostProcessing/MM Strobe Flash Shaker")] [RequireComponent(typeof(Volume))] public class MMStrobeFlashShaker : MMShaker { [MMInspectorGroup("Strobe Settings", true, 53)] [Tooltip("如果勾选,震动结束后会强制关闭 Effect,无论初始状态是什么。建议勾选。")] public bool ForceOffAfterShake = true; [MMInspectorGroup("Debug Info", true, 54)] [MMReadOnly] public bool IsActive = false; protected Volume _volume; protected StrobeFlash _strobe; protected bool _initialEnableEffect; protected bool _initialAutoFlash; protected float _initialFrequency; protected Color _initialColorHigh; protected Color _initialColorLow; protected bool _modifyExtra; protected float _targetFrequency; protected Color _targetColorHigh; protected Color _targetColorLow; protected float _originalShakeDuration; protected override void Initialization() { base.Initialization(); _volume = GetComponent(); if (!_volume.profile.TryGet(out _strobe)) { Debug.LogWarning("MMStrobeFlashShaker : No StrobeFlash found in Volume on " + name); } } protected override void GrabInitialValues() { if (_strobe != null) { _initialEnableEffect = _strobe.enableEffect.value; _initialAutoFlash = _strobe.autoFlash.value; _initialFrequency = _strobe.frequency.value; _initialColorHigh = _strobe.colorHigh.value; _initialColorLow = _strobe.colorLow.value; } } protected override void Shake() { if (_strobe == null) return; // 强制开启 _strobe.enableEffect.value = true; _strobe.autoFlash.value = true; IsActive = true; if (_modifyExtra) { _strobe.frequency.value = _targetFrequency; _strobe.colorHigh.value = _targetColorHigh; _strobe.colorLow.value = _targetColorLow; } } // 确保 Stop 被调用时执行复位 public override void Stop() { base.Stop(); // base.Stop() 会调用 ResetTargetValues,但为了保险,再次确保状态 IsActive = false; } protected override void ResetTargetValues() { base.ResetTargetValues(); IsActive = false; if (_strobe != null) { // [关键修改] 如果开启了强制关闭,直接设为 false;否则恢复初始值 if (ForceOffAfterShake) { _strobe.enableEffect.value = false; _strobe.autoFlash.value = false; } else { _strobe.enableEffect.value = _initialEnableEffect; _strobe.autoFlash.value = _initialAutoFlash; } _strobe.frequency.value = _initialFrequency; _strobe.colorHigh.value = _initialColorHigh; _strobe.colorLow.value = _initialColorLow; } } protected override void ResetShakerValues() { base.ResetShakerValues(); ShakeDuration = _originalShakeDuration; _modifyExtra = false; } // 增加 OnDisable 处理,防止游戏物体被禁用时状态残留 protected virtual void OnDisable() { if (IsActive) { ResetTargetValues(); } } public virtual void OnEvent(MMF_Feedback source, float duration, float feedbacksIntensity = 1.0f, MMChannelData channelData = null, bool resetShakerValuesAfterShake = true, bool resetTargetValuesAfterShake = true, bool forwardDirection = true, TimescaleModes timescaleMode = TimescaleModes.Scaled, bool stop = false, bool restore = false, bool modifyExtra = false, float frequency = 15f, Color colorHigh = default, Color colorLow = default) { if (!CheckEventAllowed(channelData)) return; if (stop) { Stop(); return; } if (restore) { ResetTargetValues(); return; } if (resetShakerValuesAfterShake) { _originalShakeDuration = ShakeDuration; } if (!OnlyUseShakerValues) { TimescaleMode = timescaleMode; ShakeDuration = duration; _modifyExtra = modifyExtra; _targetFrequency = frequency; _targetColorHigh = colorHigh; _targetColorLow = colorLow; } // 你的框架修改:传入 source Play(source); } public override void StartListening() { base.StartListening(); MMStrobeFlashShakeEvent.Register(OnEvent); } public override void StopListening() { base.StopListening(); MMStrobeFlashShakeEvent.Unregister(OnEvent); } } }