From c05583a365ec4021957ce38fb386c6d388725fed Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 30 Jul 2026 14:20:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(animation):=20=E6=95=8C=E4=BA=BA=E4=BE=A7?= =?UTF-8?q?=E5=8A=A8=E7=94=BB=E4=BA=8B=E4=BB=B6=E8=A1=A5=E6=8E=A5=E6=97=A0?= =?UTF-8?q?=E6=95=8C=E5=B8=A7=E4=B8=8E=E5=8F=8D=E9=A6=88=E5=9B=9B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EnableIFrame/DisableIFrame → HurtBox.SetInvincible(与玩家侧同形态, 无敌时长由动画时间轴上两事件间距表达);TriggerFeedback/PlaySFX → IFeedbackPlayer,用于音效预警。此前敌人侧只接了 7/20 个事件类型。 Co-Authored-By: Claude Opus 5 (1M context) --- .../Scripts/Animation/EnemyAnimationEvents.cs | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Assets/_Game/Scripts/Animation/EnemyAnimationEvents.cs b/Assets/_Game/Scripts/Animation/EnemyAnimationEvents.cs index ea0e9d95..ffa4c76b 100644 --- a/Assets/_Game/Scripts/Animation/EnemyAnimationEvents.cs +++ b/Assets/_Game/Scripts/Animation/EnemyAnimationEvents.cs @@ -2,6 +2,7 @@ using System; using Animancer; using BaseGames.Combat; using BaseGames.Enemies; +using BaseGames.Feedback; using UnityEngine; namespace BaseGames.Animation @@ -9,10 +10,10 @@ namespace BaseGames.Animation /// /// 敌人动画事件接收器(架构 §AnimationModule)。 /// 挂载于敌人 Prefab 根节点。负责将 Animancer 动画时间点回调路由到 - /// HitBox 激活、弹幕生成、嘶吼状态、二阶段切换等系统。 + /// HitBox 激活、弹幕生成、嘶吼状态、二阶段切换、无敌帧、反馈等系统。 /// /// 使用方式: - /// 1. 在 Inspector 中填充 _hitBoxes、_enemy。 + /// 1. 在 Inspector 中填充 _hitBoxes、_hurtBox、_enemy。 /// 2. 将每条 ClipTransition + AnimationEventConfigSO 配对添加到 _bindings。 /// 3. Awake 中 AnimationEventBinder.Bind 自动完成注入。 /// @@ -30,16 +31,23 @@ namespace BaseGames.Animation [Header("子系统引用")] [SerializeField] private HitBox[] _hitBoxes; + [SerializeField] private HurtBox _hurtBox; [SerializeField] private EnemyBase _enemy; [Header("事件绑定(每个 Clip 对应一个配置资产)")] [SerializeField] private EventBinding[] _bindings; + private IFeedbackPlayer _feedback; + private void Awake() { if (_enemy == null) _enemy = GetComponentInParent(); + // IFeedbackPlayer 由父层或同层实现(EnemyFeedback / NullFeedbackPlayer),与玩家侧同写法 + _feedback = GetComponentInParent() + ?? NullFeedbackPlayer.Instance; + foreach (var b in _bindings) AnimationEventBinder.Bind(b.clip, b.config, this); } @@ -59,6 +67,16 @@ namespace BaseGames.Animation SetHitBoxActive(payload, false); break; + // ── 无敌帧 ──────────────────────────────────────────────── + // 时长由动画时间轴上两个事件的间距表达,不在代码里写常量。 + case AnimationEventType.EnableIFrame: + _hurtBox?.SetInvincible(true); + break; + + case AnimationEventType.DisableIFrame: + _hurtBox?.SetInvincible(false); + break; + // ── 弹幕 / 技能 ─────────────────────────────────────────── case AnimationEventType.SpawnProjectile: _enemy?.SpawnProjectile(payload); @@ -78,6 +96,18 @@ namespace BaseGames.Animation _enemy?.TriggerPhaseTwo(); break; + // ── 通用反馈 ────────────────────────────────────────────── + // 音效预警:在起手帧播一段可辨识的音,让玩家提前缩小招式可能性。 + case AnimationEventType.TriggerFeedback: + if (!string.IsNullOrEmpty(payload)) + _feedback.TriggerPreset(payload); + break; + + case AnimationEventType.PlaySFX: + if (!string.IsNullOrEmpty(payload)) + _feedback.PlaySFXById(payload); + break; + // ── 状态机钩子 ──────────────────────────────────────────── case AnimationEventType.AnimationComplete: _enemy?.OnAnimationComplete(payload);