using UnityEngine; using System.Collections; namespace BaseGames.Player.States { /// /// 地面冲刺状态(架构 05_PlayerModule §2 + §12)。 /// 施加水平位移 + 无敌帧;冲刺期间重力归零,结束后恢复; /// 需解锁 AbilityType.Dash 才能进入(PlayerController 负责条件检查)。 /// public class DashState : PlayerStateBase { private float _timer; private float _cooldownTimer; private int _facingDir; public bool CanDash => _cooldownTimer <= 0f; /// 冲刺状态期间应视为无敌,PlayerController 据此跳过受击硬直。 public override bool IsInvincible => true; public DashState(PlayerController owner) : base(owner) { } public override void OnStateEnter() { Debug.Assert(Cfg != null, "[DashState] MovementConfig 未配置,请在 PlayerController Inspector 中绑定 MovementConfig SO。", _owner); _facingDir = Owner.FacingDirection; _timer = Cfg.DashDuration; // 无敌帧 Stats?.BeginInvincibility(Cfg.DashDuration + 0.05f); // 关闭重力,施加冲刺速度 Move?.SetGravityScale(0f); Move?.Dash(new Vector2(_facingDir, 0f), Cfg.DashSpeed); // 播放冲刺动画 if (AnimCfg?.Dash != null) Anim?.Play(AnimCfg.Dash); } public override void OnStateUpdate() { _timer -= Time.deltaTime; if (_timer <= 0f) EndDash(); } public override void OnStateExit() { // 恢复默认重力 Move?.SetGravityScale(Cfg.DefaultGravityScale); _cooldownTimer = Cfg.DashCooldown; } public override void OnStateFixedUpdate() { // 冲刺期间保持冲刺速度(防止摩擦力减速) if (_timer > 0f) Move?.Dash(new Vector2(_facingDir, 0f), Cfg.DashSpeed); } private void EndDash() { if (Move != null && Move.IsGrounded) Owner.TransitionTo(Owner.GetState()); else Owner.TransitionTo(Owner.GetState()); } /// 每帧减少冷却(由 PlayerController.Update 调用)。 public void TickCooldown(float dt) { if (_cooldownTimer > 0f) _cooldownTimer -= dt; } } }