using System; using Sirenix.OdinInspector; using SLSUtilities.Feedback; using UnityEngine; namespace Cielonos.MainGame.Effects.Feedback { /// /// 摄像机旋转震动反馈,通过 CameraRotationShakeEvent 触发 CinemachineRotationShaker。 /// X/Y 作用于 FollowTarget 旋转,Z 作用于 Dutch 倾斜。 /// [Serializable] [FeedbackActionColor(0.3f, 0.7f, 0.3f)] public class CameraRotationShakeAction : CinemachineActionBase { public override string DisplayName => "Camera Rotation Shake"; public Vector3 amplitude; public FloatCurveChannel intensityCurve = FloatCurveChannel.CreateDefault(); 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 attenuation = ComputeAttenuation(context); CameraRotationShakeEvent.Trigger(context, intensityCurve, finalAmplitude * attenuation); } protected override void StopEvent(FeedbackContext context) { CameraRotationShakeEvent.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; } } }