88 lines
3.7 KiB
C#
88 lines
3.7 KiB
C#
using UnityEngine;
|
||
|
||
namespace BaseGames.Player.States
|
||
{
|
||
/// <summary>
|
||
/// 下落状态。
|
||
/// - 郊狼跳:CoyoteTimer > 0 时按跳跃 → 一段跳(JumpState,使用 JumpForce)。
|
||
/// - 二段跳:CoyoteTimer 耗尽后按跳跃且 AirJumpsLeft > 0 → JumpState(使用 DoubleJumpForce)。
|
||
/// - 空中冲刺:HasAbility(AirDash) && HasAerialDash → AerialDashState。
|
||
/// - 增强下落重力(FallGravityMult)确保下落快于上升,手感紧实。
|
||
/// </summary>
|
||
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<JumpState>());
|
||
return;
|
||
}
|
||
if (Owner.AirJumpsLeft > 0)
|
||
{
|
||
// 二段跳:通过 SetDoubleJump 标记 JumpState 使用 DoubleJumpForce
|
||
Owner.UseAirJump();
|
||
Owner.GetState<JumpState>()?.SetDoubleJump(true);
|
||
_owner.TransitionTo(_owner.GetState<JumpState>());
|
||
return;
|
||
}
|
||
// 无跳跃机会:输入已消耗,静默忽略(无可用跳跃机会时静默消耗输入缓冲)
|
||
}
|
||
|
||
// ── 空中冲刺────────────────────────────────────────────────────────
|
||
if (Buffer.ConsumeDash()
|
||
&& Stats != null && Stats.HasAbility(AbilityType.AirDash))
|
||
{
|
||
var aerialDash = Owner.GetState<AerialDashState>();
|
||
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<RunState>());
|
||
else
|
||
_owner.TransitionTo(_owner.GetState<IdleState>());
|
||
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));
|
||
}
|
||
}
|
||
}
|
||
}
|