73 lines
2.3 KiB
C#
73 lines
2.3 KiB
C#
using UnityEngine;
|
||
|
||
namespace BaseGames.Player.States
|
||
{
|
||
/// <summary>
|
||
/// 空中冲刺状态(架构 05_PlayerModule §12)。
|
||
/// 与地面 DashState 独立,消耗 MaxAerialDashes 次数;
|
||
/// 空中冲刺可向任意方向(使用移动输入方向,无输入则使用朝向)。
|
||
/// </summary>
|
||
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<FallState>());
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
/// <summary>着地时重置空中冲刺次数(由 PlayerController 在着地时调用)。</summary>
|
||
public void ResetAerialDashes()
|
||
{
|
||
_aerialDashesLeft = Cfg.MaxAerialDashes;
|
||
}
|
||
}
|
||
}
|