13 KiB
07 · 反馈系统
命名空间
BaseGames.Feedback
所属文档集 ← 返回索引 · 总览
依赖 Feel v4.3 ·BaseGames.Core.Events·BaseGames.Combat
目录
- 设计原则
- Feel MMF_Player 体系
- PlayerFeedback — 玩家反馈配置
- EnemyFeedback — 敌人反馈配置
- 时间管理:子弹时间集成
- 镜头震动集成
- 音效管理
- 粒子特效规范
- UI 反馈
- 事件频道驱动的全局反馈
- FeedbackConfigSO
- 编辑器友好设计
1. 设计原则
- 零耦合:所有反馈通过事件频道或
UnityEvent触发,GameLogic 不直接调用 Feedback - 数据驱动:每种反馈配置为独立
MMF_Player资产,可在 Inspector 中调节,无需修改代码 - 分层设计:本地反馈(HitBox 命中瞬间)→ 全局反馈(OnHitConfirmed 频道)→ 时间管理(ParrySuccess)
- 像素风格适配:优先使用 Shader 闪光(Flash)而非粒子,减少视觉噪声
2. Feel MMF_Player 体系
MMF_Player 命名规范
所有 MMF_Player GameObject 命名格式:MMF_{Owner}_{EventName}
示例:
MMF_Player_OnHit(玩家受击)MMF_Player_OnAttackHit(玩家攻击命中)MMF_Player_OnParrySuccess(弹反成功)MMF_Enemy_OnHit(敌人受击)MMF_Enemy_OnDeath(敌人死亡)
MMF_Player Feedback 类型速查
| Feel Feedback 类型 | 常用场景 | 关键参数 |
|---|---|---|
MMF_Flash |
Sprite 受击白闪 | FlashColor, Duration |
MMF_SpriteRenderer |
闪烁/变色 | Color, Blink Duration |
MMF_Particles |
命中粒子特效 | ParticleSystem 引用 |
MMF_AudioSource |
播放音效 | AudioClip, Volume, Pitch Variance |
MMF_CinemachineImpulse |
镜头震动 | ImpulseSource, Velocity |
MMF_FreezeFrame |
命中冻帧 | FreezeDuration |
MMF_TimeScale |
子弹时间 | TimeScale, Duration |
MMF_TextMeshPro |
伤害数字弹出 | Value, Animation Curve |
MMF_Position |
物体位移(扑克震动) | Displacement, Curve |
MMF_Scale |
冲击缩放(南瓜弹) | Scale, Duration |
MMF_Enable |
启用/禁用 GameObject | Target |
3. IFeedbackPlayer 接口 — 反馈抽象层
为了让游戏逻辑(PlayerCombat、EnemyBase)与具体的 Feel/MMF_Player 实现零耦合,所有反馈调用必须通过 IFeedbackPlayer 接口进行:
/// <summary>
/// 反馈执行器的抽象接口。
/// GameLogic 依赖此接口,而非具体的 MMF_Player 引用。
/// </summary>
public interface IFeedbackPlayer
{
void PlayHit(HitWeight weight); // 命中反馈(轻/中/重)
void PlayParrySuccess(); // 弹反成功
void PlayTakeHit(); // 玩家受击
void PlayDeath(); // 死亡演出
void PlayHeal(); // 治疗
void PlayLandImpact(); // 落地冲击
void PlayAttackWhoosh(); // 攻击挥动音效
void PlayJumpLaunch(); // 起跳
void TriggerPreset(string presetId); // 通过 ID 触发任意预设(动画事件用)
void PlaySFXById(string sfxId); // 通过 ID 播放音效(动画事件用)
}
使用规范:
PlayerCombat、PlayerMovement等逻辑组件持有IFeedbackPlayer _feedback(通过 Inspector 注入)- 测试时可替换为
NullFeedbackPlayer(空实现),完全不需要 Feel 资产 - 新增反馈类型时先在接口声明,再在
PlayerFeedback中实现,保持单一变更点
4. PlayerFeedback — 玩家反馈配置
PlayerFeedback 组件挂载在 Player Prefab 下,实现 IFeedbackPlayer 接口,聚合所有玩家相关 MMF_Player:
受击反馈(OnTakeHit)
| Feedback | 参数 | 视觉效果 |
|---|---|---|
MMF_Flash |
白色,0.15s | Sprite 白闪(经典受击感) |
MMF_AudioSource |
SFX_Player_Hurt | 受伤音效(随机 Pitch 0.9~1.1) |
MMF_CinemachineImpulse |
Medium,0.5强度 | 镜头震动 |
MMF_FreezeFrame |
0.033s | 2帧冻帧 |
MMF_Position |
朝击退反方向 1 unit | 玩家轻微弹开 |
攻击命中反馈(OnAttackHit)
| Feedback | 参数 | 说明 |
|---|---|---|
MMF_Particles |
HitSpark Prefab,命中点生成 | 金属火花粒子 |
MMF_AudioSource |
SFX_Attack_Hit(随机 3 个变体之一) | 命中音效 |
MMF_FreezeFrame |
0.033s(2帧) | 命中停顿感 |
MMF_CinemachineImpulse |
Light,0.2强度 | 轻微镜头震 |
弹反成功反馈(OnParrySuccess)
| Feedback | 参数 | 说明 |
|---|---|---|
MMF_Flash |
金色,0.1s | Sprite 金光闪烁 |
MMF_Particles |
ParryFlash Prefab(全屏金色光圈) | 弹反标志性特效 |
MMF_AudioSource |
SFX_Parry_Success(金属碰撞音) | 清脆弹反音效 |
MMF_CinemachineImpulse |
Parry,0.7强度,带方向 | 有方向性震动 |
MMF_TimeScale |
0.25×,0.2s | 子弹时间(与 ParrySystem 同步) |
MMF_FreezeFrame |
0.066s(4帧) | 更长冻帧强调击中感 |
治疗反馈(OnHeal)
| Feedback | 参数 | 说明 |
|---|---|---|
MMF_Flash |
蓝色,0.2s | 恢复光效 |
MMF_Particles |
HealParticle Prefab | 向上飘散的蓝色粒子 |
MMF_AudioSource |
SFX_Heal | 回血音效 |
死亡反馈(OnDeath)
| Feedback | 参数 | 说明 |
|---|---|---|
MMF_AudioSource |
SFX_Player_Death | 死亡音效 |
MMF_CinemachineImpulse |
Heavy,1.0强度 | 强烈震动 |
MMF_FreezeFrame |
0.1s(6帧) | 死亡冻帧 |
MMF_Enable |
禁用 HurtBox | 防止死亡后继续受击 |
4. EnemyFeedback — 敌人反馈配置
EnemyFeedback 挂在每个敌人 Prefab 下:
受击反馈(OnHit)
| Feedback | 参数 | 说明 |
|---|---|---|
MMF_Flash |
白色,0.1s | 受击白闪 |
MMF_AudioSource |
SFX_Enemy_Hurt(按敌人类型变体) | 受伤音效 |
MMF_Particles |
HitSpark(命中位置) | 命中粒子 |
被弹反反馈(OnParried)
| Feedback | 参数 | 说明 |
|---|---|---|
MMF_Flash |
金色,0.15s | 与玩家弹反视觉对应 |
MMF_SpriteRenderer |
扭曲/Shader 效果 | 硬直视觉反馈 |
MMF_AudioSource |
SFX_Parry_Impact | 被弹反音效 |
MMF_Position |
小幅后退 | 轻微击退特效 |
死亡反馈(OnDeath)
| Feedback | 参数 | 说明 |
|---|---|---|
MMF_AudioSource |
SFX_Enemy_Death | 死亡音效 |
MMF_Particles |
DeathParticle Prefab | 死亡解体粒子 |
MMF_Enable |
禁用 Rigidbody2D / Colliders | 防止尸体物理继续 |
MMF_FreezeFrame |
0.05s(3帧) | 击杀冻帧 |
5. 时间管理:子弹时间集成
子弹时间通过两套系统协调:
Feel MMTimeManager(主要)
- 注册所有
MMTimeManagerListener ParrySystem.TriggerParrySuccess()→MMTimeScaleEvent广播MMTimeManager接收后修改Time.timeScale- 时间恢复:Lerp 方式平滑还原(
LerpSpeed = 20)
与 Animancer 的配合
- Animancer 动画默认使用
Time.timeScale(跟随子弹时间减速) - 特例:UI 动画、音频播放必须用
Time.unscaledDeltaTime - 检测敌人动画速率被子弹时间自动降低(无需额外配置)
6. 镜头震动集成
详见 02_CameraSystem。
Feel 与 Cinemachine Impulse 的桥接
Feel MMF_CinemachineImpulse → 内部调用 CinemachineImpulseSource.GenerateImpulse() → CinemachineImpulseListener 响应。
PlayerFeedback 中每种震动类型对应 ImpulseSource(Inspector 中拖入引用):
| 震动类型 | 来源 ImpulseSource | 说明 |
|---|---|---|
| Light | ImpulseSource_Light |
普通命中 |
| Medium | ImpulseSource_Medium |
玩家受伤 |
| Heavy | ImpulseSource_Heavy |
玩家死亡 / Boss 重击 |
| Parry | ImpulseSource_Parry |
弹反成功(带方向性) |
7. 音效管理
音效 SO 资产结构
AudioEventSO 封装音效播放参数(非特定 AudioSource),通过事件频道解耦:
| 字段 | 类型 | 说明 |
|---|---|---|
Clips |
AudioClip[] |
随机选取其中一个播放 |
Volume |
float |
基础音量(0~1) |
PitchMin |
float |
Pitch 随机范围最小值 |
PitchMax |
float |
Pitch 随机范围最大值 |
MixerGroup |
AudioMixerGroup |
SFX / Music / UI 混音组 |
所有 MMF_AudioSource 通过 AudioEventSO 播放音效(而非直接引用 AudioClip),实现随机音调变化。
音效资产路径
Assets/Audio/SFX/
├── Player/
│ ├── SFX_Player_Hurt.asset
│ ├── SFX_Player_Death.asset
│ ├── SFX_Attack_Hit.asset ← 含3个变体Clip
│ ├── SFX_Parry_Success.asset
│ └── SFX_Heal.asset
├── Enemies/
│ ├── SFX_Enemy_Hurt_Generic.asset
│ └── SFX_Enemy_Death_Generic.asset
└── World/
├── SFX_Footstep.asset
└── SFX_Landing.asset
8. 粒子特效规范
| 特效 Prefab | 触发来源 | 生命周期 | 说明 |
|---|---|---|---|
FX_HitSpark |
攻击命中 | 0.3s 后自销毁 | 金属火花(4~6 粒子) |
FX_ParryFlash |
弹反成功 | 0.5s 后自销毁 | 金色光圈(全屏扩散) |
FX_HealParticle |
玩家治疗 | 1.0s 后自销毁 | 蓝色粒子上飘 |
FX_EnemyDeath |
敌人死亡 | 1.5s 后自销毁 | 解体粒子(按敌人主题色) |
FX_DustCloud |
玩家落地 | 0.5s 后自销毁 | 落地灰尘 |
FX_DashTrail |
玩家冲刺 | 0.4s 后自销毁 | 冲刺残影(Sprite Fade) |
像素风格适配:所有粒子使用 Render Mode: Billboard,粒子贴图与角色 PPU(32 PPU)保持一致,避免模糊。
9. UI 反馈
伤害数字(FloatingText)
- 触发:
OnHitConfirmed事件频道 - 从对象池中取
FloatingTextPrefab,在命中位置生成 - 数字内容:
DamageInfo.FinalDamage - 弹反反击:数字显示为金色 + 粗体(
FinalDamage为 3× 时额外标记) - 动画:向上飘 0.8s + 淡出
HP 血条动画
OnPlayerHPChanged事件频道驱动- 满格 HP 以绿色实心显示,扣除部分以红色渐出动画表示(延迟 0.2s 开始缩短,视觉缓冲)
Soul 槽动画
OnSoulChanged事件频道驱动- 弹反成功 +33 时,Soul 槽显示扫光动画(金色高亮流过 1/3 槽)
10. 事件频道驱动的全局反馈
GlobalFeedbackController 组件(单例,挂在 [Managers] GO 上)监听全局频道并触发对应 MMF_Player:
| 频道 | 触发反馈 |
|---|---|
OnPlayerDied |
停止音乐、播放死亡演出(慢慢音量淡出,画面泛红) |
OnBossFightStarted |
停止环境音乐、淡入 Boss 战BGM |
OnBossFightEnded |
Boss 死亡演出(震动+特效+音乐过渡) |
OnRoomEntered |
淡出 → 淡入(场景切换遮罩) |
11. FeedbackConfigSO
FeedbackConfigSO 全局配置,存放于 Assets/ScriptableObjects/Config/FeedbackConfigSO.asset:
| 参数 | 类型 | 推荐值 | 说明 |
|---|---|---|---|
HitFreezeFrames |
int |
2 | 命中冻帧帧数 |
ParryFreezeFrames |
int |
4 | 弹反冻帧帧数 |
SfxVolumeMaster |
float |
1.0 | SFX 总音量(0~1) |
HapticsEnabled |
bool |
true | 手柄震动开关(P2) |
FloatingTextPoolSize |
int |
20 | 伤害数字对象池大小 |
ParticlePoolSize |
int |
30 | 粒子特效对象池大小 |
12. 编辑器友好设计
MMF_Player 预览支持
Feel 原生支持在 Editor 非 Play Mode 下预览 MMF_Player:
- Inspector 底部的"▶ Play"按钮可单独预览每组反馈
Preview in Editor模式下验证视觉效果,无需进入 Play Mode
FX 对象池监控(Play Mode Inspector)
┌─ GlobalFeedbackController ──────────────────────┐
│ FloatingText Pool: 14 / 20 available │
│ Particle Pool : 28 / 30 available │
│ ───────────────────────────────────────────── │
│ [Test: Player Hurt] [Test: Parry Success] │
│ [Test: Enemy Hit ] [Test: Boss Phase Change] │
└────────────────────────────────────────────────┘
反馈效果全局开关(调试用)
FeedbackDebugOverlay(编辑器 Play Mode 下叠加):
[Toggle Screen Shake]:开关镜头震动[Toggle Freeze Frames]:开关冻帧[Toggle Particles]:开关粒子特效[Toggle Bullet Time]:开关子弹时间
方便策划/美术人员单独调试某类反馈。