using System; using Animancer; using BaseGames.Combat; using BaseGames.Enemies; using UnityEngine; namespace BaseGames.Animation { /// /// 敌人动画事件接收器(架构 §AnimationModule)。 /// 挂载于敌人 Prefab 根节点。负责将 Animancer 动画时间点回调路由到 /// HitBox 激活、弹幕生成、嘶吼状态、二阶段切换等系统。 /// /// 使用方式: /// 1. 在 Inspector 中填充 _hitBoxes、_enemy。 /// 2. 将每条 ClipTransition + AnimationEventConfigSO 配对添加到 _bindings。 /// 3. Awake 中 AnimationEventBinder.Bind 自动完成注入。 /// public class EnemyAnimationEvents : MonoBehaviour, IAnimationEventHandler { [Serializable] public struct EventBinding { [Tooltip("Animancer ClipTransition(需与动画组件中同一引用绑定)。")] public ClipTransition clip; [Tooltip("对应的 AnimationEventConfigSO 资产。")] public AnimationEventConfigSO config; } [Header("子系统引用")] [SerializeField] private HitBox[] _hitBoxes; [SerializeField] private EnemyBase _enemy; [Header("事件绑定(每个 Clip 对应一个配置资产)")] [SerializeField] private EventBinding[] _bindings; private void Awake() { if (_enemy == null) _enemy = GetComponentInParent(); foreach (var b in _bindings) AnimationEventBinder.Bind(b.clip, b.config, this); } // ── IAnimationEventHandler ───────────────────────────────────────── public void HandleEvent(AnimationEventType type, string payload) { switch (type) { // ── 命中判定 ────────────────────────────────────────────── case AnimationEventType.EnableHitBox: SetHitBoxActive(payload, true); break; case AnimationEventType.DisableHitBox: SetHitBoxActive(payload, false); break; // ── 弹幕 / 技能 ─────────────────────────────────────────── case AnimationEventType.SpawnProjectile: _enemy?.SpawnProjectile(payload); break; // ── 嘶吼 ────────────────────────────────────────────────── case AnimationEventType.RoarStart: _enemy?.SetRoaring(true); break; case AnimationEventType.RoarEnd: _enemy?.SetRoaring(false); break; // ── 二阶段切换 ──────────────────────────────────────────── case AnimationEventType.PhaseTwoStart: _enemy?.TriggerPhaseTwo(); break; // ── 状态机钩子 ──────────────────────────────────────────── case AnimationEventType.AnimationComplete: _enemy?.OnAnimationComplete(payload); break; } } // ── 私有辅助 ─────────────────────────────────────────────────────── /// /// 按 Id 激活或停用 HitBox。 /// payload 为空时操作所有 HitBox;非空时仅操作 Id 匹配的 HitBox。 /// private void SetHitBoxActive(string id, bool active) { if (_hitBoxes == null) return; bool matchAll = string.IsNullOrEmpty(id); foreach (var hb in _hitBoxes) { if (hb == null) continue; if (matchAll || hb.Id == id) { if (active) hb.Activate(); else hb.Deactivate(); } } } } }