using System; using Sirenix.OdinInspector; using SLSUtilities.Feedback; using UnityEngine; namespace Cielonos.MainGame.Effects.Feedback { /// /// 摄像机轨道旋转反馈动作,通过 CameraOrbitEvent 触发 CameraOrbitShaker。 /// 支持两种模式: /// - Additive:曲线值作为偏移量叠加到初始角度上 /// - TargetValue:从当前值平滑运动到指定的目标角度 /// [Serializable] [FeedbackActionColor(0.3f, 0.7f, 0.95f)] public class CameraOrbitAction : CinemachineActionBase { public override string DisplayName => "Camera Orbit"; public enum OrbitMode { /// /// 曲线输出值作为角度偏移量,叠加到触发时的初始角度上。 /// Additive, /// /// 类似 DoTween:指定目标角度 (endValue),通过缓动曲线从当前位置平滑运动到目标。 /// TargetValue } [TitleGroup("生效相机设置")] [LabelText("在 FreeLook (自由视角) 相机下生效")] public bool enableInFreeLook = true; [LabelText("在 LockTarget (锁定视角) 相机下生效")] public bool enableInLockTarget = true; // ===== 水平公转设置 (Yaw) ===== [TitleGroup("水平公转设置 (Yaw)")] [LabelText("启用水平公转")] public bool enableYaw = true; [LabelText("水平公转模式")] [ShowIf("enableYaw")] public OrbitMode yawMode = OrbitMode.Additive; // Yaw Additive 参数 [LabelText("水平公转曲线 (Yaw)")] [ShowIf("@enableYaw && yawMode == OrbitMode.Additive")] public FloatCurveChannel horizontalCurve = FloatCurveChannel.CreateDefault(0f, 360f); // Yaw TargetValue 参数 [LabelText("目标角度 (Yaw)")] [Tooltip("目标水平公转角度。0° = 玩家正面,180° = 玩家背面。可以超过 360°。")] [ShowIf("@enableYaw && yawMode == OrbitMode.TargetValue")] public float endHorizontalValue = 0f; [LabelText("缓动曲线 (Yaw)")] [Tooltip("水平公转缓动曲线:归一化时间 [0,1] 映射到插值进度 [0,1]。")] [ShowIf("@enableYaw && yawMode == OrbitMode.TargetValue")] [ShakeCurvePreset] public AnimationCurve yawEaseCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); [LabelText("使用最短路径")] [Tooltip("开启时,相机会选择最近的旋转方向移向目标角度(防止 360 度穿帮旋转);关闭时,将按照绝对数值插值。")] [ShowIf("@enableYaw && yawMode == OrbitMode.TargetValue")] public bool shortestPath = true; // ===== 垂直公转设置 (Pitch) ===== [TitleGroup("垂直公转设置 (Pitch)")] [LabelText("启用垂直公转")] public bool enablePitch = true; [LabelText("垂直公转模式")] [ShowIf("enablePitch")] public OrbitMode pitchMode = OrbitMode.Additive; // Pitch Additive 参数 [LabelText("垂直公转曲线 (Pitch)")] [ShowIf("@enablePitch && pitchMode == OrbitMode.Additive")] public FloatCurveChannel verticalCurve = FloatCurveChannel.CreateDefault(0f, 0f); // Pitch TargetValue 参数 [LabelText("目标角度 (Pitch)")] [Tooltip("目标垂直公转角度。硬锁相机下为相对锁定仰角的偏移量;自由相机下为绝对仰角。")] [ShowIf("@enablePitch && pitchMode == OrbitMode.TargetValue")] public float endVerticalValue = 0f; [LabelText("缓动曲线 (Pitch)")] [Tooltip("垂直公转缓动曲线:归一化时间 [0,1] 映射到插值进度 [0,1]。")] [ShowIf("@enablePitch && pitchMode == OrbitMode.TargetValue")] [ShakeCurvePreset] public AnimationCurve pitchEaseCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f); protected override void TriggerEvent(FeedbackContext context) { CameraOrbitEvent.Trigger(context, this); } protected override void StopEvent(FeedbackContext context) { CameraOrbitEvent.Trigger(context, this, true); } public override bool Validate(out string error) { error = null; return true; } } }