70 lines
2.5 KiB
C#
70 lines
2.5 KiB
C#
using BaseGames.Combat;
|
||
|
||
namespace BaseGames.Player.States
|
||
{
|
||
/// <summary>
|
||
/// 地面攻击状态(3 段连击)。
|
||
/// 由 PlayerController 实例化,AttackEvent 触发切换。
|
||
/// 通过 Animancer 帧事件驱动 HitBox 激活/关闭。
|
||
/// </summary>
|
||
public class AttackState : PlayerStateBase
|
||
{
|
||
private int _comboIndex;
|
||
|
||
public AttackState(PlayerController owner) : base(owner) { }
|
||
|
||
public override void OnStateEnter()
|
||
{
|
||
_comboIndex = 0;
|
||
PlayAttackClip();
|
||
Input.AttackEvent += OnAttackInput;
|
||
}
|
||
|
||
public override void OnStateExit()
|
||
{
|
||
Input.AttackEvent -= OnAttackInput;
|
||
Owner.Combat?.DisableAllWeaponHitBoxes();
|
||
}
|
||
|
||
public override void OnStateUpdate() { }
|
||
public override void OnStateFixedUpdate() { }
|
||
|
||
// ── 内部 ──────────────────────────────────────────────────────────────
|
||
|
||
private void PlayAttackClip()
|
||
{
|
||
// ⚠️ 字段名 GroundAttacks(非 AttackChainClips)
|
||
var clip = AnimCfg.GroundAttacks[_comboIndex];
|
||
var state = Anim.Play(clip);
|
||
var events = state.Events(this);
|
||
events.OnEnd = OnClipEnd;
|
||
|
||
// HitBox 由 Animancer 归一化时间事件驱动(时间点配置于 PlayerAnimationConfigSO)
|
||
var timings = AnimCfg?.GroundAttackTimings;
|
||
float enterTime = timings != null && _comboIndex < timings.Length
|
||
? timings[_comboIndex].HitBoxEnter : 0.3f;
|
||
float exitTime = timings != null && _comboIndex < timings.Length
|
||
? timings[_comboIndex].HitBoxExit : 0.6f;
|
||
events.Add(enterTime, () => Owner.Combat?.EnableWeaponHitBox(AttackDirection.Ground));
|
||
events.Add(exitTime, () => Owner.Combat?.DisableAllWeaponHitBoxes());
|
||
}
|
||
|
||
private void OnClipEnd()
|
||
{
|
||
Owner.Combat?.DisableAllWeaponHitBoxes();
|
||
Owner.TransitionTo(Owner.GetState<IdleState>());
|
||
}
|
||
|
||
private void OnAttackInput()
|
||
{
|
||
// 连击段数从配置 SO 动态读取,无须修改代码即可支持任意段数连击
|
||
int maxCombo = AnimCfg?.GroundAttacks?.Length ?? 1;
|
||
if (_comboIndex < maxCombo - 1)
|
||
{
|
||
_comboIndex++;
|
||
PlayAttackClip();
|
||
}
|
||
}
|
||
}
|
||
}
|