66 lines
2.1 KiB
C#
66 lines
2.1 KiB
C#
using System.Collections;
|
||
using Animancer;
|
||
using UnityEngine;
|
||
using BaseGames.Enemies.Perception;
|
||
|
||
namespace BaseGames.Enemies.Abilities
|
||
{
|
||
/// <summary>
|
||
/// 循环追击 + 体接触伤害能力。
|
||
/// 追击期间每帧更新 MoveTo,失去感知后收招退出并恢复巡逻状态。
|
||
/// 可复用于任何需要"追击+接触伤害循环"的敌人。
|
||
/// </summary>
|
||
public class ContactChaseAbility : EnemyAbilityBase
|
||
{
|
||
[Header("动画")]
|
||
[SerializeField] private ClipTransition _loopClip;
|
||
[SerializeField] private ClipTransition _endClip;
|
||
|
||
[Header("感知与接触伤害")]
|
||
[SerializeField] private BodyContactDamage _contactDamage;
|
||
[SerializeField] private EnemySensorHub _sensorHub;
|
||
|
||
[Tooltip("用于追击感知判断的传感器槽位名,通常为 \"aggro\"")]
|
||
[SerializeField] private string _aggroSlotName = "aggro";
|
||
|
||
protected override IEnumerator ExecuteCoroutine()
|
||
{
|
||
Phase = AbilityRunState.Active;
|
||
|
||
if (_loopClip.Clip != null)
|
||
_animancer.Play(_loopClip);
|
||
|
||
if (_contactDamage != null)
|
||
_contactDamage.enabled = true;
|
||
|
||
while (true)
|
||
{
|
||
if (_enemy.PlayerTransform == null) break;
|
||
if (_sensorHub != null && !_sensorHub.IsDetecting(_aggroSlotName, _enemy.PlayerTransform.gameObject))
|
||
break;
|
||
_enemy.MoveTo(_enemy.PlayerTransform.position);
|
||
yield return null;
|
||
}
|
||
|
||
if (_contactDamage != null)
|
||
_contactDamage.enabled = false;
|
||
|
||
_enemy.StopMovement();
|
||
|
||
if (_endClip.Clip != null)
|
||
{
|
||
_animancer.Play(_endClip);
|
||
yield return EnemyAbilityWaits.Get(_endClip.Clip.length);
|
||
}
|
||
|
||
_enemy.SetAiPhase(AiPhase.Patrol);
|
||
}
|
||
|
||
protected override void OnInterrupted(InterruptReason reason)
|
||
{
|
||
if (_contactDamage != null)
|
||
_contactDamage.enabled = false;
|
||
}
|
||
}
|
||
}
|