using UnityEngine;
namespace BaseGames.Player.States
{
///
/// 下落状态。
/// - 郊狼跳:CoyoteTimer > 0 时按跳跃 → 一段跳(JumpState,使用 JumpForce)。
/// - 二段跳:CoyoteTimer 耗尽后按跳跃且 AirJumpsLeft > 0 → JumpState(使用 DoubleJumpForce)。
/// - 空中冲刺:HasAbility(AirDash) && HasAerialDash → AerialDashState。
/// - 增强下落重力(FallGravityMult)确保下落快于上升,手感紧实。
///
public class FallState : PlayerStateBase
{
public FallState(PlayerController owner) : base(owner) { }
public override void OnStateEnter()
{
if (AnimCfg?.Fall != null)
Anim.Play(AnimCfg.Fall);
}
public override void OnStateUpdate()
{
// ── 跳跃输入(郊狼跳 / 二段跳)────────────────────────────────────
if (Buffer.ConsumeJump())
{
if (Move.HasCoyoteTime)
{
// 郊狼跳:一段跳,使用 JumpForce
_owner.TransitionTo(_owner.GetState());
return;
}
if (Owner.AirJumpsLeft > 0)
{
// 二段跳:通过 SetDoubleJump 标记 JumpState 使用 DoubleJumpForce
Owner.UseAirJump();
Owner.GetState()?.SetDoubleJump(true);
_owner.TransitionTo(_owner.GetState());
return;
}
// 无跳跃机会:输入已消耗,静默忽略(无可用跳跃机会时静默消耗输入缓冲)
}
// ── 空中冲刺────────────────────────────────────────────────────────
if (Buffer.ConsumeDash()
&& Stats != null && Stats.HasAbility(AbilityType.AirDash))
{
var aerialDash = Owner.GetState();
if (aerialDash != null && aerialDash.HasAerialDash)
{
_owner.TransitionTo(aerialDash);
return;
}
}
// ── 着地──────────────────────────────────────────────────────────
if (Move.IsGrounded)
{
Move.ZeroVelocity();
if (Mathf.Abs(Input.MoveInput.x) > 0.1f)
_owner.TransitionTo(_owner.GetState());
else
_owner.TransitionTo(_owner.GetState());
return;
}
}
public override void OnStateFixedUpdate()
{
// 空中水平移动:有输入时立即覆盖至目标速度;无输入时施加空气阻力保留动量
if (Mathf.Abs(Input.MoveInput.x) > 0.01f)
Move.Move(Input.MoveInput.x * Cfg.RunSpeed);
else
Move.ApplyAirDrag(Cfg.AirDragFactor);
// 增强下落重力(FallGravityMult:下落比上升更快,手感更紧实)
if (Move.Rb.velocity.y < 0f)
{
float extraGrav = Physics2D.gravity.y * (Cfg.FallGravityMult - 1f) * Time.fixedDeltaTime;
Move.Rb.velocity = new Vector2(
Move.Rb.velocity.x,
Mathf.Max(Move.Rb.velocity.y + extraGrav, -Cfg.MaxFallSpeed));
}
}
}
}