using System; using Sirenix.OdinInspector; using SLSUtilities.Feedback; using UnityEngine; namespace Cielonos.MainGame.Effects.Feedback { /// /// 摄像机位移震动反馈,通过 CameraPositionShakeEvent 触发 CinemachinePositionShaker。 /// [Serializable] [FeedbackActionColor(0.4f, 0.8f, 0.4f)] public class CameraPositionShakeAction : CinemachineActionBase { public override string DisplayName => "Camera Position Shake"; [TitleGroup("位移震动设置")] [LabelText("震动曲线")] public FloatCurveChannel intensityCurve = FloatCurveChannel.CreateDefault(); [TitleGroup("位移震动设置")] [LabelText("振幅")] public Vector3 amplitude = new Vector3(0.5f, 0.5f, 0f); [TitleGroup("方向设置")] public CameraDirectionSettings directionSettings = new CameraDirectionSettings(); [TitleGroup("距离衰减")] [LabelText("启用衰减")] public bool useAttenuation; [ShowIf("useAttenuation")] [LabelText("衰减范围")] public float attenuationRange = 50f; [ShowIf("useAttenuation")] [LabelText("衰减曲线")] public AnimationCurve attenuationCurve = new AnimationCurve( new Keyframe(0f, 1f), new Keyframe(1f, 0f) ); protected override void TriggerEvent(FeedbackContext context) { Vector3 finalAmplitude = directionSettings.TransformAmplitude(amplitude, context.owner); float intensityMultiplier = ComputeAttenuation(context); CameraPositionShakeEvent.Trigger(context, intensityCurve, finalAmplitude * intensityMultiplier); } protected override void StopEvent(FeedbackContext context) { CameraPositionShakeEvent.Trigger(context, intensityCurve, Vector3.zero, true); } private float ComputeAttenuation(FeedbackContext context) { if (!useAttenuation || context.owner == null) return 1f; Camera mainCamera = Camera.main; if (mainCamera == null) return 1f; float distance = Vector3.Distance(context.owner.position, mainCamera.transform.position); float normalizedDistance = Mathf.Clamp01(distance / attenuationRange); return attenuationCurve.Evaluate(normalizedDistance); } public override bool Validate(out string error) { error = null; return true; } } }