using System.Collections; using Animancer; using BaseGames.Combat; using UnityEngine; namespace BaseGames.Enemies.Abilities { /// /// 近战攻击带后摇脆弱窗口能力:攻击动画期间按时间比例激活 HitBox, /// 攻击完成后开放 HurtBox(脆弱窗口),窗口结束后恢复正常。 /// 可复用于任何"攻击后有反击窗口"的敌人技能。 /// public class MeleeVulnerabilityAbility : EnemyAbilityBase { [Header("动画")] [SerializeField] private ClipTransition _attackClip; [Header("碰撞")] [SerializeField] private HitBox _hitBox; [SerializeField] private HurtBox _hurtBox; [Header("打击时间(0~1 归一化,基于 Clip 时长)")] [SerializeField, Range(0f, 1f)] private float _hitEnterT = 0.30f; [SerializeField, Range(0f, 1f)] private float _hitExitT = 0.60f; [Header("后摇脆弱窗口")] [Tooltip("HurtBox 激活时间(秒)")] [SerializeField] private float _staggerDuration = 1.0f; protected override IEnumerator ExecuteCoroutine() { Phase = AbilityRunState.Active; if (_attackClip.Clip == null) yield break; float len = _attackClip.Clip.length; float t = 0f; bool active = false; var dmgSrc = _config?.attackSequence?.Length > 0 ? _config.attackSequence[0].damageSource : null; _animancer.Play(_attackClip); while (t < len) { t += Time.deltaTime; if (!active && t >= len * _hitEnterT) { _hitBox?.Activate(dmgSrc, _transform); active = true; } if (active && t >= len * _hitExitT) { _hitBox?.Deactivate(); active = false; } yield return null; } if (active) _hitBox?.Deactivate(); // 后摇脆弱窗口 if (_hurtBox != null) _hurtBox.enabled = true; yield return EnemyAbilityWaits.Get(_staggerDuration); if (_hurtBox != null) _hurtBox.enabled = false; } protected override void OnInterrupted(InterruptReason reason) { _hitBox?.Deactivate(); if (_hurtBox != null) _hurtBox.enabled = false; } } }