using System; using System.Collections; using Animancer; using BaseGames.Combat; using UnityEngine; namespace BaseGames.Enemies.Behaviors { /// /// 死亡前摇无敌演出(零代码替代每敌人专属的 Die() 重写)。 /// /// 会委托本组件:停行为树 / 停移动、停用受击框,播放前摇动画并等待, /// 期间敌人处于无敌(),演出结束后回调真正的死亡清理。 /// 前摇动画上可放置 SpawnProjectile 动画事件,配合 在演出中生成小怪。 /// /// [DisallowMultipleComponent] public class EnemyDeathSequence : MonoBehaviour, IEnemyDeathSequence { [Header("前摇动画")] [Tooltip("死亡前摇动画(无敌演出);为空则跳过演出直接进入死亡清理")] [SerializeField] private ClipTransition _deathPreClip; [Tooltip("前摇演出时长(秒)")] [Min(0f)][SerializeField] private float _duration = 3f; [Header("演出期间")] [Tooltip("演出期间停用的受击框(防止演出中被打断或二次受伤);对象池复用时 OnSpawn 自动恢复")] [SerializeField] private HurtBox[] _hurtBoxesToDisable; [Tooltip("演出开始时停止行为树(防止 BT 继续 Tick 覆盖演出动画)")] [SerializeField] private bool _stopBehaviorTree = true; [Tooltip("演出开始时停止移动")] [SerializeField] private bool _stopMovement = true; private EnemyBase _enemy; private AnimancerComponent _animancer; private void Awake() { _enemy = GetComponentInParent(); _animancer = _enemy != null ? _enemy.Animancer : GetComponentInParent(); if (_enemy == null) Debug.LogError($"[EnemyDeathSequence] {name} 找不到 EnemyBase。", this); } // 对象池复用:出生时恢复受击框(演出中曾被停用) private void OnEnable() { if (_enemy != null) _enemy.Spawned += RestoreHurtBoxes; } private void OnDisable() { if (_enemy != null) _enemy.Spawned -= RestoreHurtBoxes; } public void Play(Action onComplete) { StartCoroutine(Sequence(onComplete)); } private IEnumerator Sequence(Action onComplete) { if (_stopBehaviorTree) _enemy?.StopBehaviorTree(); if (_stopMovement) _enemy?.StopMovement(); SetHurtBoxesEnabled(false); if (_deathPreClip.Clip != null && _animancer != null) { _animancer.Play(_deathPreClip); if (_duration > 0f) yield return new WaitForSeconds(_duration); } onComplete?.Invoke(); } private void RestoreHurtBoxes() => SetHurtBoxesEnabled(true); private void SetHurtBoxesEnabled(bool enabled) { if (_hurtBoxesToDisable == null) return; foreach (var hb in _hurtBoxesToDisable) if (hb != null) hb.enabled = enabled; } } }