using UnityEngine; namespace BaseGames.Player { [CreateAssetMenu(menuName = "BaseGames/Player/AnimationConfig")] public class PlayerAnimationConfigSO : ScriptableObject { [Header("移动")] public AnimationClip Idle; public AnimationClip Run; public AnimationClip Jump; public AnimationClip Fall; public AnimationClip Dash; [Header("墙")] public AnimationClip WallSlide; [Header("受伤 / 死亡")] public AnimationClip Hurt; public AnimationClip Dead; [Tooltip("受击硬直最短持续时间(秒),动画早于此时间结束也不会提前退出)")] public float HurtDuration = 0.4f; [Header("弹簧")] public AnimationClip UseSpring; [Header("地面攻击(连招序列)")] public AnimationClip[] GroundAttacks; /// 每段连击的 HitBox 开启/关闭时间点(归一化 0-1),与 GroundAttacks 索引对应。 [System.Serializable] public struct AttackTimings { [Tooltip("HitBox 开启时间点(归一化 0-1)")] [UnityEngine.Range(0f, 1f)] public float HitBoxEnter; [Tooltip("HitBox 关闭时间点(归一化 0-1)")] [UnityEngine.Range(0f, 1f)] public float HitBoxExit; } [Header("地面攻击 HitBox 激活窗口(归一化时间 0-1)")] [Tooltip("每段连击 HitBox 开启/关闭时间点,与 GroundAttacks 索引对应")] public AttackTimings[] GroundAttackTimings = { new AttackTimings { HitBoxEnter = 0.3f, HitBoxExit = 0.6f } }; [Header("空中攻击")] public AnimationClip AirAttack; public AnimationClip UpAttack; public AnimationClip DownAttack; // 戳击 (Pogo) [Header("弹反")] public AnimationClip ParryStart; public AnimationClip ParrySuccess; [Header("游泳")] public AnimationClip SwimIdle; public AnimationClip SwimMove; /// 按连招步骤取地面攻击动画,越界自动取最后一个。 public AnimationClip GetAttackClip(int step) { if (GroundAttacks == null || GroundAttacks.Length == 0) return null; return step < GroundAttacks.Length ? GroundAttacks[step] : GroundAttacks[^1]; } } }