using UnityEngine;
using BaseGames.Combat;
namespace BaseGames.Player.States
{
///
/// 空中攻击状态(架构 05_PlayerModule §2)。
/// HitBox 时间由 ComboStepConfig.hitBoxEnter/Exit 驱动;结束后按 recoveryTime 延迟取消窗口。
///
public class AirAttackState : PlayerStateBase
{
private float _recoveryEndTime;
public AirAttackState(PlayerController owner) : base(owner) { }
public override void OnStateEnter()
{
var step = Owner.Weapon?.ActiveWeapon?.GetDirStep(AttackDirection.Air);
float spd = Stats?.AnimatorSpeedMultiplier ?? 1f;
if (step?.clip?.Clip != null)
{
var animState = Anim.Play(step.Value.clip);
animState.Speed *= spd;
var events = animState.Events(this);
events.OnEnd = OnClipEnd;
var s = step.Value;
events.Add(s.hitBoxEnter, () => Owner.Combat?.EnableWeaponHitBox(AttackDirection.Air, s.hitBoxId));
events.Add(s.hitBoxExit, () => Owner.Combat?.DisableAllWeaponHitBoxes());
}
else
{
Owner.Combat?.EnableWeaponHitBox(AttackDirection.Air);
OnClipEnd();
}
}
public override void OnStateExit()
{
Owner.Combat?.DisableAllWeaponHitBoxes();
Move?.SetCancelWindowOpen(false);
}
public override void OnStateUpdate()
{
if (Time.time >= _recoveryEndTime)
Move.SetCancelWindowOpen(true);
}
private void OnClipEnd()
{
Owner.Combat?.DisableAllWeaponHitBoxes();
var step = Owner.Weapon?.ActiveWeapon?.GetDirStep(AttackDirection.Air);
float spd = Stats?.AnimatorSpeedMultiplier ?? 1f;
float recovery = (step?.recoveryTime ?? 0.05f) / spd;
_recoveryEndTime = Time.time + recovery;
Move.SetCancelWindowOpen(false);
Owner.TransitionTo(Owner.GetState());
}
}
}