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;
}
}
}