112 lines
4.5 KiB
C#
112 lines
4.5 KiB
C#
using System;
|
|
using Animancer;
|
|
using BaseGames.Combat;
|
|
using BaseGames.Enemies;
|
|
using UnityEngine;
|
|
|
|
namespace BaseGames.Animation
|
|
{
|
|
/// <summary>
|
|
/// 敌人动画事件接收器(架构 §AnimationModule)。
|
|
/// 挂载于敌人 Prefab 根节点。负责将 Animancer 动画时间点回调路由到
|
|
/// HitBox 激活、弹幕生成、嘶吼状态、二阶段切换等系统。
|
|
///
|
|
/// 使用方式:
|
|
/// 1. 在 Inspector 中填充 _hitBoxes、_enemy。
|
|
/// 2. 将每条 ClipTransition + AnimationEventConfigSO 配对添加到 _bindings。
|
|
/// 3. Awake 中 AnimationEventBinder.Bind 自动完成注入。
|
|
/// </summary>
|
|
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<EnemyBase>();
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
// ── 私有辅助 ───────────────────────────────────────────────────────
|
|
|
|
/// <summary>
|
|
/// 按 Id 激活或停用 HitBox。
|
|
/// payload 为空时操作所有 HitBox;非空时仅操作 Id 匹配的 HitBox。
|
|
/// </summary>
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|