using UnityEngine; namespace BaseGames.Player.States { /// /// 空中冲刺状态(架构 05_PlayerModule §12)。 /// 与地面 DashState 独立,消耗 MaxAerialDashes 次数; /// 空中冲刺可向任意方向(使用移动输入方向,无输入则使用朝向)。 /// public class AerialDashState : PlayerStateBase { private float _timer; private int _aerialDashesLeft; private int _facingDir; public bool HasAerialDash => _aerialDashesLeft > 0; public AerialDashState(PlayerController owner) : base(owner) { _aerialDashesLeft = 1; } public override void OnStateEnter() { _aerialDashesLeft = Mathf.Max(0, _aerialDashesLeft - 1); _facingDir = Owner.FacingDirection; _timer = Cfg.DashDuration; // 无敌帧 Stats?.BeginInvincibility(Cfg.DashDuration + 0.05f); // 关闭重力,施加冲刺速度(空中冲刺不改变垂直速度) Move?.SetGravityScale(0f); float dir = Input.MoveInput.x != 0 ? Mathf.Sign(Input.MoveInput.x) : _facingDir; Move?.Dash(new Vector2(dir, 0f), Cfg.DashSpeed); // 播放冲刺动画(复用地面冲刺动画) if (AnimCfg?.Dash != null) Anim?.Play(AnimCfg.Dash); } public override void OnStateUpdate() { _timer -= Time.deltaTime; if (_timer <= 0f) { Move?.SetGravityScale(Cfg.DefaultGravityScale); Owner.TransitionTo(Owner.GetState()); } } public override void OnStateExit() { Move?.SetGravityScale(Cfg.DefaultGravityScale); } public override void OnStateFixedUpdate() { // 冲刺期间锁定速度 if (_timer > 0f) { float dir = Input.MoveInput.x != 0 ? Mathf.Sign(Input.MoveInput.x) : _facingDir; Move?.Dash(new Vector2(dir, 0f), Cfg.DashSpeed); } } /// 着地时重置空中冲刺次数(由 PlayerController 在着地时调用)。 public void ResetAerialDashes() { _aerialDashesLeft = Cfg.MaxAerialDashes; } } }