using UnityEngine; using MoreMountains.Feedbacks; using MoreMountains.Tools; using UnityEngine.Rendering; using SLSFramework.Rendering.PostProcessing; namespace MoreMountains.FeedbacksForThirdParty { public struct MMRadialBlurShakeEvent { public static void Register(Delegate callback) { OnEvent += callback; } public static void Unregister(Delegate callback) { OnEvent -= callback; } // 修改点:在参数列表中增加了 modifyCenter 和 center public delegate void Delegate(MMF_Feedback source, AnimationCurve distortionCurve, float duration, float remapMin, float remapMax, bool relativeDistortion = false, 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 modifyCenter = false, Vector2 center = default); // 新增参数放在最后,带默认值以保持兼容性 public static event Delegate OnEvent; public static void Trigger(MMF_Feedback source, AnimationCurve distortionCurve, float duration, float remapMin, float remapMax, bool relativeDistortion = false, 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 modifyCenter = false, Vector2 center = default) { OnEvent?.Invoke(source, distortionCurve, duration, remapMin, remapMax, relativeDistortion, feedbacksIntensity, channelData, resetShakerValuesAfterShake, resetTargetValuesAfterShake, forwardDirection, timescaleMode, stop, restore, modifyCenter, center); } } [AddComponentMenu("More Mountains/Feedbacks/Shakers/PostProcessing/MM Radial Blur Shaker")] [RequireComponent(typeof(Volume))] public class MMRadialBlurShaker : MMShaker { [MMInspectorGroup("Radial Blur", true, 52)] [Tooltip("是否在现有值的基础上叠加")] public bool RelativeIntensity = false; [Tooltip("模糊强度的震动曲线")] public AnimationCurve ShakeIntensity = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0)); [Tooltip("曲线 0 对应的 Blur Radius 值")] public float RemapIntensityZero = 0f; [Tooltip("曲线 1 对应的 Blur Radius 值")] public float RemapIntensityOne = 1f; protected Volume _volume; protected RadialBlur _radialBlur; // 初始值记录 protected float _initialIntensity; protected float _initialCenterX; protected float _initialCenterY; // 震动时的临时变量 protected bool _modifyCenter; protected Vector2 _targetCenter; protected float _originalShakeDuration; protected bool _originalRelativeIntensity; protected AnimationCurve _originalShakeIntensity; protected float _originalRemapIntensityZero; protected float _originalRemapIntensityOne; protected override void Initialization() { base.Initialization(); _volume = this.gameObject.GetComponent(); if (_volume.profile.TryGet(out _radialBlur)) { // 获取成功 } else { Debug.LogWarning("MMRadialBlurShaker : No RadialBlur Override found in the Volume on " + this.name); } } protected override void GrabInitialValues() { if (_radialBlur != null) { _initialIntensity = _radialBlur.blurRadius.value; _initialCenterX = _radialBlur.radialCenterX.value; _initialCenterY = _radialBlur.radialCenterY.value; } } protected override void Shake() { if (_radialBlur == null) return; // 1. 处理模糊强度 (Radius) float newIntensity = ShakeFloat(ShakeIntensity, RemapIntensityZero, RemapIntensityOne, RelativeIntensity, _initialIntensity); _radialBlur.blurRadius.value = newIntensity; // 2. 处理模糊中心 (Center) - 新增逻辑 // 只有当 Feedback 要求修改中心时才覆盖,否则保持原样 (通常是 0.5) if (_modifyCenter) { _radialBlur.radialCenterX.value = _targetCenter.x; _radialBlur.radialCenterY.value = _targetCenter.y; } else { // 如果不修改,我们强制设为默认中心(0.5, 0.5)或者初始值? // 根据你的描述:如果不开启,默认中心为(0.5,0.5)。 // 为了保险,这里可以不做操作(保留Volume当前值),也可以强制复位。 // 建议:不做操作,让ResetTargetValues去负责恢复。 } } protected override void ResetTargetValues() { base.ResetTargetValues(); if (_radialBlur != null) { _radialBlur.blurRadius.value = _initialIntensity; // 复位中心点 _radialBlur.radialCenterX.value = _initialCenterX; _radialBlur.radialCenterY.value = _initialCenterY; } } protected override void ResetShakerValues() { base.ResetShakerValues(); ShakeDuration = _originalShakeDuration; ShakeIntensity = _originalShakeIntensity; RemapIntensityZero = _originalRemapIntensityZero; RemapIntensityOne = _originalRemapIntensityOne; RelativeIntensity = _originalRelativeIntensity; // 震动结束,重置 modifyCenter 标记,防止后续影响 _modifyCenter = false; } public virtual void OnMMRadialBlurShakeEvent(MMF_Feedback source, AnimationCurve distortionCurve, float duration, float remapMin, float remapMax, bool relativeDistortion = false, 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 modifyCenter = false, Vector2 center = default) { if (!CheckEventAllowed(channelData)) return; if (stop) { Stop(); return; } if (restore) { ResetTargetValues(); return; } if (!Interruptible && Shaking) return; _resetShakerValuesAfterShake = resetShakerValuesAfterShake; _resetTargetValuesAfterShake = resetTargetValuesAfterShake; if (resetShakerValuesAfterShake) { _originalShakeDuration = ShakeDuration; _originalShakeIntensity = ShakeIntensity; _originalRemapIntensityZero = RemapIntensityZero; _originalRemapIntensityOne = RemapIntensityOne; _originalRelativeIntensity = RelativeIntensity; } if (!OnlyUseShakerValues) { TimescaleMode = timescaleMode; ShakeDuration = duration; ShakeIntensity = distortionCurve; RemapIntensityZero = remapMin * feedbacksIntensity; RemapIntensityOne = remapMax * feedbacksIntensity; RelativeIntensity = relativeDistortion; ForwardDirection = forwardDirection; // 接收并存储中心点参数 _modifyCenter = modifyCenter; _targetCenter = center; } Play(source); } public override void StartListening() { base.StartListening(); MMRadialBlurShakeEvent.Register(OnMMRadialBlurShakeEvent); } public override void StopListening() { base.StopListening(); MMRadialBlurShakeEvent.Unregister(OnMMRadialBlurShakeEvent); } } }