76 lines
2.6 KiB
C#
76 lines
2.6 KiB
C#
using System.Collections;
|
||
using Animancer;
|
||
using BaseGames.Combat;
|
||
using UnityEngine;
|
||
|
||
namespace BaseGames.Enemies.Abilities
|
||
{
|
||
/// <summary>
|
||
/// 多段砸地能力:起手 → 循环砸地(N次,带 HitBox 激活)→ 收招。
|
||
/// 支持霸体(ABL SO 配置 interruptOnHurt=false),后摇时间可配置。
|
||
/// 可复用于任何多段地面攻击型敌人。
|
||
/// </summary>
|
||
public class RepeatSlamAbility : EnemyAbilityBase
|
||
{
|
||
[Header("动画")]
|
||
[SerializeField] private ClipTransition _startClip;
|
||
[SerializeField] private ClipTransition _loopClip;
|
||
[SerializeField] private ClipTransition _endClip;
|
||
|
||
[Header("打击")]
|
||
[SerializeField] private HitBox _hitBox;
|
||
|
||
[Header("行为配置")]
|
||
[Tooltip("每次砸地时 HitBox 激活时长(秒)")]
|
||
[SerializeField] private float _hitActiveTime = 0.15f;
|
||
[Tooltip("砸地次数")]
|
||
[SerializeField] private int _slamCount = 2;
|
||
[Tooltip("最后一次砸地收招后额外等待时间(秒)")]
|
||
[SerializeField] private float _staggerDuration = 1.2f;
|
||
|
||
protected override IEnumerator ExecuteCoroutine()
|
||
{
|
||
Phase = AbilityRunState.Active;
|
||
|
||
if (_startClip.Clip != null)
|
||
{
|
||
_animancer.Play(_startClip);
|
||
yield return EnemyAbilityWaits.Get(_startClip.Clip.length);
|
||
}
|
||
|
||
for (int i = 0; i < _slamCount; i++)
|
||
{
|
||
if (_loopClip.Clip != null)
|
||
{
|
||
_animancer.Play(_loopClip);
|
||
float preHit = Mathf.Max(0f, _loopClip.Clip.length - _hitActiveTime - 0.05f);
|
||
yield return EnemyAbilityWaits.Get(preHit);
|
||
}
|
||
|
||
var dmgSrc = _config?.attackSequence?.Length > 0 ? _config.attackSequence[0].damageSource : null;
|
||
_hitBox?.Activate(dmgSrc, _transform);
|
||
yield return EnemyAbilityWaits.Get(_hitActiveTime);
|
||
_hitBox?.Deactivate();
|
||
|
||
if (i < _slamCount - 1)
|
||
yield return EnemyAbilityWaits.Get(0.1f);
|
||
}
|
||
|
||
if (_endClip.Clip != null)
|
||
{
|
||
_animancer.Play(_endClip);
|
||
yield return EnemyAbilityWaits.Get(_endClip.Clip.length + _staggerDuration);
|
||
}
|
||
else
|
||
{
|
||
yield return EnemyAbilityWaits.Get(_staggerDuration);
|
||
}
|
||
}
|
||
|
||
protected override void OnInterrupted(InterruptReason reason)
|
||
{
|
||
_hitBox?.Deactivate();
|
||
}
|
||
}
|
||
}
|