Files
zeling_v2/Docs/ThirdPart/Feel_Technical_Evaluation.md
2026-05-19 23:20:44 +08:00

43 KiB
Raw Permalink Blame History

Feel v4.3 技术评估与使用手册

版本: Feel v4.3 (More Mountains)
Unity 要求: 2019.4+
可选依赖: Cinemachine · Post Processing · TextMesh Pro · Animation 2D
许可: Unity Asset Store EULA
包路径: Assets/Feel/
官方文档: https://feel-docs.moremountains.com/
API 文档: https://feel-docs.moremountains.com/API/


目录

  1. 概述与设计哲学
  2. 架构总览
  3. MMF_Player — 反馈播放器
  4. MMF_Feedback — 反馈基类
  5. MMFeedbackTiming — 时序配置
  6. 所有 Feedback 类型分类
  7. Shaker 系统
  8. Spring 弹簧系统
  9. Sequencing 序列系统
  10. 通道系统 (Channel)
  11. MMTools 核心工具库
  12. MMTools Foundation 扩展
  13. NiceVibrations 触觉反馈
  14. 第三方集成模块
  15. Demo 场景一览
  16. 与 BaseGames 架构集成方案
  17. 性能分析与优化建议
  18. 优缺点总结
  19. 总结与建议

1. 概述与设计哲学

1.1 什么是 Feel

Feel 是 More Mountains 打造的 游戏手感 (Game Feel) 工具套件,旨在用最少的代码为游戏添加丰富的视听反馈效果。其核心是 MMFeedbacks 系统 — 一个可视化的反馈编排引擎,允许策划和程序在 Inspector 中组合各种效果(震屏、粒子、音效、动画、后处理等)并一键播放。

核心理念:

将 "游戏手感" 从硬编码中解放出来,通过可组合、可配置的反馈列表,让策划在 Inspector 中直接调试最终效果。

1.2 三大模块

模块 路径 职责
MMFeedbacks Feel/MMFeedbacks/ 反馈播放器、74+ 种反馈类型、Shaker、Spring、Sequencing
MMTools Feel/MMTools/ 基础工具库(事件系统、对象池、单例模式、状态机、音频管理等)
NiceVibrations Feel/NiceVibrations/ iOS/Android/手柄触觉反馈 API

1.3 核心设计原则

原则 说明
可视化编排 所有反馈在 Inspector 中拖拽组合,所见即所得
零代码上手 一行 PlayFeedbacks() 即可触发整套效果编排
模块化反馈 每个效果是独立的 Feedback 类,自由组合
通道隔离 Feedback 通过 Channel 广播事件到对应 Shaker
时序精确 支持延迟、冷却、重复、序列、方向控制
全平台 跨渲染管线URP/HDRP/Built-in、跨平台触觉

2. 架构总览

2.1 系统架构图

MMF_Player (反馈播放器 — MonoBehaviour)
  ├── List<MMF_Feedback> FeedbacksList
  │     ├── MMF_CameraShake    → 广播 CameraShakeEvent
  │     ├── MMF_Particles      → 直接操控 ParticleSystem
  │     ├── MMF_AudioSource    → 播放 AudioClip
  │     ├── MMF_Scale          → 动画化 Transform.scale
  │     ├── MMF_PositionSpring → 驱动 MMSpringVector3
  │     └── ... (74+ 种 Feedback)
  │
  ├── MMFeedbackTiming (每个 Feedback 独立的时序配置)
  │     ├── InitialDelay / CooldownDuration
  │     ├── NumberOfRepeats / RepeatForever
  │     ├── PlayDirection / DirectionCondition
  │     └── Sequence / Quantized / BPM
  │
  └── Events
        ├── OnPlay / OnPause / OnResume / OnComplete / ...

Shaker 层:
  MMCameraShaker ← 监听 CameraShakeEvent (Channel=X)
  MMLightShaker  ← 监听 LightShakeEvent  (Channel=X)
  MMPositionShaker ← ...

Spring 层:
  MMSpringFloat/Vector2/Vector3/Vector4/Color
  └── 物理弹簧模拟 → CurrentValue 每帧更新

2.2 反馈生命周期

Awake → PreInitialization
  ↓
Start → Initialization
  ↓
PlayFeedbacks() ─→ 遍历 FeedbacksList
  ↓                   ├── Timing.InitialDelay
  │                   ├── Chance 概率检查
  │                   ├── CustomPlayFeedback() ← 子类实现
  │                   ├── Timing.NumberOfRepeats
  │                   └── Timing.CooldownDuration
  ↓
StopFeedbacks() → CustomStopFeedback()
  ↓
OnDisable / OnDestroy

2.3 目录结构

Assets/Feel/
├── MMFeedbacks/
│   ├── MMFeedbacks/
│   │   ├── Core/                    # 核心系统
│   │   │   ├── MMF_Player/          # MMF_Player.cs, MMF_Feedback.cs 基类
│   │   │   ├── MMChannels/          # 通道系统
│   │   │   ├── Legacy/              # 旧版兼容
│   │   │   └── ObjectPool/          # 反馈专用对象池
│   │   ├── Feedbacks/               # 74 个标准 Feedback 类型
│   │   ├── Shakers/                 # 24 个 Shaker 类型
│   │   ├── Springs/                 # 弹簧系统 (Core + Feedbacks)
│   │   ├── Sequencing/              # 序列系统
│   │   └── MMFloatingText/          # 浮动文本效果
│   ├── MMFeedbacksForThirdParty/    # 第三方集成
│   │   ├── Cinemachine/             # 3 个 Feedback + Shaker
│   │   ├── URP/                     # 5+ 后处理 Feedback
│   │   ├── HDRP/                    # 5+ 后处理 Feedback
│   │   ├── PostProcessing/          # v2 后处理集成
│   │   ├── TextMeshPro/             # 7+ TMP Feedback
│   │   ├── NiceVibrations/          # 触觉 Feedback
│   │   ├── UIToolkit/               # 5 个 UI Toolkit Feedback
│   │   └── VisualEffectGraph/       # VFX Graph 集成
│   ├── Editor/                      # Inspector 编辑器
│   └── Demos/                       # 反馈演示
├── MMTools/
│   ├── Core/                        # 13 个核心工具模块
│   │   ├── MMEvents/                # 轻量事件系统
│   │   ├── MMAudio/                 # 音频管理器、播放列表
│   │   ├── MMObjectPool/            # 泛型对象池
│   │   ├── MMSingletons/            # 单例模式基类
│   │   ├── MMStateMachine/          # 泛型状态机
│   │   ├── MMTimeManager/           # 时间缩放管理
│   │   ├── MMTween/                 # 缓动/补间动画
│   │   ├── MMPropertyControllers/   # 属性动态控制器
│   │   ├── MMRadio/                 # SO 广播系统
│   │   ├── MMSaveLoad/              # 存档系统
│   │   ├── MMHelpers/               # 数学/几何/颜色等工具
│   │   ├── MMAttributes/            # 自定义 Inspector 特性
│   │   └── MMExtensions/            # C# 扩展方法
│   └── Foundation/                  # 高级工具
│       ├── MMAchievements/          # 成就系统
│       ├── MMAI/                    # AI 工具
│       ├── MMAnimation/             # 动画工具
│       ├── MMControls/              # 控制助手
│       └── MMLoot/                  # 掉落表/抽奖系统
├── NiceVibrations/
│   ├── Scripts/                     # 触觉 API
│   │   └── Components/              # HapticController, HapticSource 等
│   ├── HapticSamples/               # 触觉预设样本
│   └── Plugins/                     # 原生插件
├── FeelDemos/                       # 标准演示场景 (~17个)
├── FeelDemosURP/                    # URP 演示
└── FeelDemosHDRP/                   # HDRP 演示

3. MMF_Player — 反馈播放器

3.1 核心属性

属性 类型 说明
FeedbacksList List<MMF_Feedback> 反馈列表
IsPlaying bool 是否正在播放
TotalDuration float 所有反馈的总时长
PlayCount int 播放次数计数
SkippingToTheEnd bool 是否正在跳到结尾
Direction Directions 播放方向 (TopToBottom / BottomToTop)
FeedbacksIntensity float 全局强度乘数
CanPlayWhileAlreadyPlaying bool 允许重叠播放
CanPlay bool 是否允许播放
CooldownDuration float 冷却时间
InitialDelay float 初始延迟
PerformanceMode bool 性能模式(禁用 Inspector 实时刷新)
GlobalMMFeedbacksActive static bool 全局反馈开关

3.2 自动化选项

属性 说明
AutoInitialization 自动初始化
AutoPlayOnStart Start() 时自动播放
AutoPlayOnEnable OnEnable() 时自动播放
InitializationMode 初始化时机

3.3 时间缩放

属性 说明
TimescaleMultiplier 时间缩放乘数
PlayerTimescaleMode 时标模式 (Scaled / Unscaled)
ForceTimescaleMode 是否强制时标模式到所有子反馈

3.4 距离范围

属性 说明
OnlyPlayIfWithinRange 仅在范围内播放
RangeCenter 范围中心 Transform
RangeDistance 范围距离

3.5 核心方法

// === 播放 ===
void PlayFeedbacks()
void PlayFeedbacks(Vector3 position, float feedbacksIntensity = 1.0f, bool forceRevert = false)
void PlayFeedbacksInReverse()
void PlayFeedbacksInReverse(Vector3 position, float feedbacksIntensity = 1.0f)
void PlayFeedbacksOnlyIfReversed()
void PlayFeedbacksOnlyIfNormalDirection()
IEnumerator PlayFeedbacksCoroutine(Vector3 position, float feedbacksIntensity = 1.0f)
IEnumerator PlayFeedbacksAfterFrames(int framesAmount)

// === 停止与控制 ===
void StopFeedbacks(Vector3 position, float feedbacksIntensity = 1.0f)
void StopAllFeedbacks(bool revert = false)
void PauseFeedbacks()
void ResumeFeedbacks()
void SkipToTheEnd(Vector3 position, float feedbacksIntensity = 1.0f)
void ResetFeedbacks()
void ForceInitialValue(Vector3 position, float feedbacksIntensity = 1.0f)
void Revert()  // 反转播放方向

// === 初始化 ===
void Initialization(bool forceInitIfPlaying = false)
void PreInitialization()

// === 查询 ===
float GetTime()
float GetDeltaTime()
bool HasFeedbackStillPlaying()
bool FeedbackCanPlay(MMF_Feedback feedback)

3.6 使用示例

public class HitReaction : MonoBehaviour
{
    [SerializeField] MMF_Player hitFeedback;

    public void OnHit(float damage)
    {
        // 一行调用即可触发整套反馈(震屏 + 粒子 + 音效 + 缩放弹跳)
        hitFeedback.PlayFeedbacks(transform.position, damage / 100f);
    }
}

4. MMF_Feedback — 反馈基类

4.1 核心属性

属性 类型 说明
Active bool 反馈是否活跃
Label string 反馈标签
Owner MMF_Player 所属播放器
IsPlaying bool 是否正在播放
FeedbackDuration float 反馈持续时间
TotalDuration float 含重复的总时长
Chance float 播放概率 (0-100)
Timing MMFeedbackTiming 时序配置

4.2 通道配置

属性 说明
ChannelMode 通道模式 (IntMMChannel)
Channel 整数通道 ID
MMChannelDefinition MMChannel ScriptableObject

4.3 随机化

属性 说明
RandomizeOutput 是否随机化输出强度
RandomMultiplier 强度随机范围 (Vector2)
RandomizeDuration 是否随机化持续时间
RandomDurationMultiplier 时长随机范围

4.4 距离衰减

属性 说明
UseRange 是否启用距离范围
RangeDistance 范围距离
UseRangeFalloff 是否使用衰减曲线
RangeFalloff 衰减曲线 (AnimationCurve)

4.5 生命周期虚方法(子类重写)

// 核心生命周期
protected virtual void CustomPlayFeedback(Vector3 position, float feedbacksIntensity)
protected virtual void CustomStopFeedback(Vector3 position, float feedbacksIntensity)
protected virtual void CustomSkipToTheEnd(Vector3 position, float feedbacksIntensity)
protected virtual void CustomForceInitialValue(Vector3 position, float feedbacksIntensity)
protected virtual void CustomInitialization(MMF_Player owner)

// 自动化
public virtual void AutomaticShakerSetup()
protected virtual void AutomateTargetAcquisition()

// 流控
public virtual IEnumerator Pause { get; }
public virtual bool HoldingPause { get; }
public virtual bool LooperPause { get; }
public virtual bool LooperStart { get; }

4.6 自定义 Feedback 示例

[AddComponentMenu("")]
[FeedbackHelp("用于在目标 Renderer 上闪烁颜色")]
[FeedbackPath("Custom/ColorFlash")]
public class MMF_ColorFlash : MMF_Feedback
{
    [MMFInspectorGroup("Target", true)]
    public Renderer TargetRenderer;
    public Color FlashColor = Color.white;
    public float Duration = 0.1f;

    public override float FeedbackDuration
    {
        get => Duration;
        set => Duration = value;
    }

    protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity)
    {
        if (TargetRenderer == null) return;
        float intensity = ComputeIntensity(feedbacksIntensity, position);
        Color color = Color.Lerp(Color.white, FlashColor, intensity);
        TargetRenderer.material.color = color;
        Owner.StartCoroutine(ResetColor());
    }

    IEnumerator ResetColor()
    {
        yield return new WaitForSeconds(Duration);
        TargetRenderer.material.color = Color.white;
    }
}

5. MMFeedbackTiming — 时序配置

每个 Feedback 实例自带一个 MMFeedbackTiming 对象,控制其时序行为。

5.1 基本时序

字段 类型 默认值 说明
InitialDelay float 0 播放前延迟(秒)
CooldownDuration float 0 两次播放间冷却(秒)
TimescaleMode TimescaleModes Scaled 是否受 Time.timeScale 影响

5.2 重复配置

字段 默认值 说明
NumberOfRepeats 0 额外重复次数0 = 仅播放一次)
RepeatForever false 无限重复
DelayBetweenRepeats 1 两次重复间延迟(秒)

5.3 播放次数限制

字段 说明
LimitPlayCount 是否限制最大播放次数
MaxPlayCount 最大播放次数
SetPlayCountToZeroOnReset 重置时清零计数

5.4 方向控制

字段 说明
MMFeedbacksDirectionCondition Always / OnlyWhenForwards / OnlyWhenBackwards
PlayDirection FollowMMFeedbacksDirection / OppositeMMFeedbacksDirection / AlwaysNormal / AlwaysRewind

5.5 强度控制

字段 说明
ConstantIntensity true = 忽略父级强度乘数
UseIntensityInterval 仅在强度范围 [Min, Max) 内播放
IntensityIntervalMin / Max 强度区间

5.6 停止行为

字段 说明
InterruptsOnStop true = 调用 Stop 时中断此反馈
ExcludeFromHoldingPauses true = 不阻塞 HoldingPause
ContributeToTotalDuration 是否计入 Player 总时长

5.7 序列关联

字段 说明
Sequence 关联的 MMSequence 资源
TrackID 序列轨道 ID
Quantized 是否量化到 BPM
TargetBPM 目标 BPM

6. 所有 Feedback 类型分类

Feel 内置 74 个标准 Feedback,加上第三方集成约 100+ 种

6.1 动画 (4)

类名 功能
MMF_Animation 触发 Animator 参数、播放动画
MMF_AnimationCrossfade 两个动画状态间交叉淡变
MMF_AnimatorSpeed 改变 Animator 播放速度
MMF_Wiggle 对象在两个值间快速摆动

6.2 音频 (10)

类名 功能
MMF_AudioSource 播放/停止/暂停 AudioSource
MMF_AudioSourceVolume 改变音量
MMF_AudioSourcePitch 改变音调
MMF_AudioSourceStereoPan 改变立体声平衡
MMF_AudioFilterDistortion 失真滤波效果
MMF_AudioFilterEcho 回声滤波效果
MMF_AudioFilterHighPass 高通滤波效果
MMF_AudioFilterLowPass 低通滤波效果
MMF_AudioFilterReverb 混响滤波效果
MMF_AudioMixerSnapshotTransition AudioMixer 快照过渡

6.3 摄像机 (7)

类名 功能
MMF_CameraShake 摄像机位置震动
MMF_CameraFieldOfView 改变透视 FOV
MMF_CameraOrthographicSize 改变正交 Size
MMF_CameraClippingPlanes 改变 Near/Far 裁剪
MMF_CameraZoom 快速缩放视角
MMF_PositionShake 目标对象位置震动
MMF_Flash 屏幕/对象闪白

6.4 变换 (15)

类名 功能
MMF_Position 动画化位置World/Local/RectTransform
MMF_Rotation 动画化旋转
MMF_Scale 动画化缩放
MMF_RotationShake 旋转震动
MMF_ScaleShake 缩放震动
MMF_SquashAndStretch 压缩伸展动画
MMF_LookAt 朝向目标
MMF_RotatePositionAround 围绕点旋转
MMF_DestinationTransform 移动到目标 Transform
MMF_SetParent 改变父对象
MMF_PositionSpring 弹簧位置动画
MMF_RotationSpring 弹簧旋转动画
MMF_ScaleSpring 弹簧缩放动画
MMF_SquashAndStretchSpring 弹簧压缩伸展

6.5 UI (15)

类名 功能
MMF_Image 改变 Image Sprite/Color
MMF_Graphic 改变 Graphic 颜色/透明度
MMF_GraphicCrossFade 两颜色间淡变
MMF_Text 改变 Text 内容
MMF_TextColor 改变 Text 颜色
MMF_ImageMaterial 改变 Image 材质
MMF_ImageRaycastTarget 改变 raycastTarget
MMF_ImageTextureOffset 改变纹理 UV 偏移
MMF_ImageTextureScale 改变纹理 UV 缩放
MMF_CanvasGroupBlocksRaycasts 改变 CanvasGroup 射线
MMF_TextureScale 改变 Renderer 纹理缩放
MMF_TextureOffset 改变 Renderer 纹理偏移
MMF_Material 改变 Renderer 材质
MMF_MaterialSetProperty 设置材质属性
MMF_Flicker 对象快速闪烁

6.6 光照 (2)

类名 功能
MMF_Light 改变 Light 强度/颜色/范围
MMF_Skybox 改变天空盒材质

6.7 粒子 (2)

类名 功能
MMF_Particles 播放粒子系统
MMF_ParticlesInstantiation 实例化粒子预制体

6.8 物理 (4)

类名 功能
MMF_Collider 启用/禁用 3D 碰撞体
MMF_Collider2D 启用/禁用 2D 碰撞体
MMF_Rigidbody 应用 3D 物理力/冲量
MMF_Rigidbody2D 应用 2D 物理力/冲量

6.9 对象控制 (5)

类名 功能
MMF_SetActive 启用/禁用 GameObject
MMF_Enable 启用/禁用 Component
MMF_Destroy 销毁对象
MMF_InstantiateObject 实例化预制体
MMF_ReferenceHolder 保存和应用对象引用

6.10 时间与流控 (6)

类名 功能
MMF_Pause 暂停反馈序列
MMF_HoldingPause 等待所有前序反馈完成后继续
MMF_Looper 循环控制器
MMF_LooperStart 循环起点标记
MMF_TimescaleModifier 修改 Time.timeScale
MMF_FreezeFrame 冻结帧(时间 = 0

6.11 事件与嵌套 (4)

类名 功能
MMF_Events 触发 UnityEvent / MMF 事件
MMF_Feedbacks 触发另一个 MMF_Player
MMF_PlayerControl 控制其他 Player 播放/停止
MMF_PlayerChain 顺序播放多个 Player

6.12 渲染/着色器 (3)

类名 功能
MMF_SpriteRenderer 改变 SpriteRenderer Sprite/Color
MMF_ShaderGlobal 设置全局 Shader 属性
MMF_VideoPlayer 控制 VideoPlayer

6.13 其他 (2)

类名 功能
MMF_Blink 对象快速淡显淡隐
MMF_UnloadScene 卸载指定场景

7. Shaker 系统

7.1 工作原理

Shaker 是放在目标对象上的组件,监听特定 Channel 上的事件。当 Feedback 广播事件时,对应 Channel 的 Shaker 执行震动。

MMF_CameraShake (Feedback)
  ↓ 广播 CameraShakeEvent (Channel=0)
MMCameraShaker (Shaker, 挂在 Camera 上, Channel=0)
  ↓ 监听并执行
Camera.transform 震动

7.2 MMShaker 基类 API

属性 说明
ShakeDuration 震动持续时间
PlayOnAwake 启动时自动播放
PermanentShake 永久震动
Interruptible 允许中断
AlwaysResetTargetValuesAfterShake 震后重置值
OnlyUseShakerValues 忽略事件参数
CooldownBetweenShakes 冷却时间
TimescaleMode 时标模式

虚方法

protected virtual void Initialization()
public virtual void StartShaking()
protected virtual void ShakeStarts()
protected virtual void Shake()         // 每帧震动逻辑
protected virtual void ShakeComplete()
protected virtual void GrabInitialValues()

7.3 所有 Shaker 类型 (24)

分类 Shaker 功能
音频 (8) MMAudioSourceVolumeShaker 震动音量
MMAudioSourcePitchShaker 震动音调
MMAudioSourceStereoPanShaker 震动立体声
MMAudioFilterDistortionShaker 震动失真
MMAudioFilterEchoShaker 震动回声
MMAudioFilterHighPassShaker 震动高通
MMAudioFilterLowPassShaker 震动低通
MMAudioFilterReverbShaker 震动混响
摄像机 (7) MMCameraShaker 震动相机位置
MMCameraShakerRotation 震动相机旋转
MMCameraFieldOfViewShaker 震动 FOV
MMCameraOrthographicSizeShaker 震动正交 Size
MMCameraClippingPlanesShaker 震动裁剪面
MMCameraZoom 摄像机缩放
MMPositionShaker 震动对象位置
变换 (4) MMRotationShaker 震动旋转
MMScaleShaker 震动缩放
MMBlink 快速闪烁
MMWiggle 摆动效果
光照/渲染 (3) MMLightShaker 震动灯光
MMSpriteRendererShaker 震动精灵颜色
MMFlash 屏幕闪白
反馈 (1) MMFeedbacksShaker 侦听并触发反馈

8. Spring 弹簧系统

8.1 概述

Spring 系统提供基于物理弹簧模型的动画驱动。与传统 Tween 不同Spring 动画具有自然的过冲和振荡效果,非常适合 UI 弹入弹出、受击反馈等场景。

弹簧公式: F = -kx - cv

  • k — 刚度(由 Frequency 决定)
  • x — 与目标值的偏移
  • c — 阻尼(由 Damping 决定)
  • v — 当前速度

8.2 核心类型

泛型参数 用途
MMSpringFloat float 单值弹簧(透明度、大小等)
MMSpringVector2 Vector2 2D 弹簧UV、2D 位置)
MMSpringVector3 Vector3 3D 弹簧(位置、旋转、缩放)
MMSpringVector4 Vector4 4D 弹簧
MMSpringColor Color 颜色弹簧RGBA

8.3 核心参数

参数 范围 默认 说明
Damping 0.01-1.0 0.4 阻尼比。低 = 长时间振荡,高 = 快速收敛
Frequency 1-20+ 6 振荡频率。低 = 缓慢弹跳,高 = 快速弹跳
LockX/Y/Z/W bool false 锁定轴/通道

8.4 核心方法

// 移动
void MoveTo(T newValue)              // 设置目标值
void MoveToInstant(T newValue)       // 立即到达
void MoveToAdditive(T newValue)      // 叠加移动
void MoveToSubtractive(T newValue)   // 减去移动
void MoveToRandom(T min, T max)      // 随机目标

// 冲击
void Bump(T bumpAmount)              // 给速度施加冲击
void BumpRandom(T min, T max)        // 随机冲击

// 控制
void Stop()                          // 停止,当前值 = 目标值
void Finish()                        // 立即完成到目标值
void SetInitialValue(T value)        // 设置初始值
void RestoreInitialValue()           // 恢复到初始值

// 更新
void UpdateSpringValue(float deltaTime) // 每帧更新模拟

8.5 MMSpringClampSettings

字段 说明
ClampMin / ClampMax 启用最小/最大值限制
ClampMinValue / ClampMaxValue 限制值
ClampMinBounce / ClampMaxBounce 到达边界时反弹

8.6 Spring Feedback

Feedback 说明
MMF_PositionSpring 弹簧驱动位置
MMF_RotationSpring 弹簧驱动旋转
MMF_ScaleSpring 弹簧驱动缩放
MMF_SquashAndStretchSpring 弹簧压缩伸展
MMF_SpringFloat 通用浮点弹簧
MMF_SpringVector2/3/4 通用向量弹簧
MMF_SpringColor 颜色弹簧

9. Sequencing 序列系统

9.1 概述

Sequencing 系统允许按节奏/时间线编排反馈播放,适合音乐节奏游戏、定时动画编排等场景。

9.2 核心类

MMSequence (ScriptableObject):

[CreateAssetMenu(menuName = "MoreMountains/Sequencer/MMSequence")]
public class MMSequence : ScriptableObject
{
    public float Length;                           // 序列长度(秒)
    public MMSequenceList OriginalSequence;         // 原始序列数据
    public bool Quantized;                         // 是否量化
    public int TargetBPM;                          // 目标 BPM
    public List<MMSequenceList> QuantizedSequence;  // 量化后数据
    public List<MMSequenceTrack> SequenceTracks;    // 轨道定义
    public float EndSilenceDuration;                // 末尾静默

    public void SortOriginalSequence();             // 按时间排序
    public void QuantizeOriginalSequence();         // 量化序列
}

MMSequencer (MonoBehaviour):

public class MMSequencer : MonoBehaviour
{
    public void Play();
    public void Pause();
    public void Resume();
    public void Stop();
    public void Seek(float time);
    public bool IsPlaying { get; }
    public float PlaybackSpeed { get; set; }
}

MMFeedbacksSequencer: 将 MMF_Player 关联到序列轨道上事件触发。

MMInputSequenceRecorder: 录制输入到序列资产。


10. 通道系统 (Channel)

10.1 概述

Channel 是 Feedback 与 Shaker 之间的通信桥梁,确保反馈事件发送到正确的 Shaker。

10.2 两种模式

模式 说明 适用场景
Int 通道 使用整数 ID 简单场景,快速设置
MMChannel (SO) 使用 ScriptableObject 资产 类型安全,推荐

10.3 使用要点

Feedback 配置:
  ChannelMode = MMChannel
  MMChannelDefinition = "MainCamera" (SO 资产)

Shaker 配置(挂在目标对象上):
  ChannelMode = MMChannel
  MMChannelDefinition = "MainCamera" (同一个 SO 资产)

→ 事件通过相同的 MMChannel 匹配

关键: Feedback 和 Shaker 必须使用相同的 Channel,否则事件无法送达。


11. MMTools 核心工具库

11.1 MMEvents — 轻量事件系统

// 定义事件结构
public struct MyEvent { public float Value; }

// 监听
MMEventManager.AddListener<MyEvent>(OnMyEvent);

// 触发
MMEventManager.TriggerEvent(new MyEvent { Value = 1f });

// 取消
MMEventManager.RemoveListener<MyEvent>(OnMyEvent);

11.2 MMAudio — 音频管理

组件 功能
MMSoundManager 全局声音管理中枢(播放、停止、淡入淡出、分组)
MMPlaylist 播放列表循环管理
MMAudioAnalyzer 音频频谱分析

11.3 MMObjectPool — 泛型对象池

public class MMObjectPool<T> where T : Component
{
    T GetPooled();
    void DestroyPooled(T obj);
    void DestroyAll();
}

public interface IMMPoolable
{
    void OnMMPooled();    // 进入池
    void OnMMUnpooled();  // 离开池
}

11.4 MMSingletons — 单例模式

说明
MMSingleton<T> 标准单例,场景卸载时销毁
MMPersistentSingleton<T> 持久单例,DontDestroyOnLoad

11.5 MMStateMachine — 泛型状态机

public class MMStateMachine<T> where T : class
{
    void ChangeState(T newState);
    void GoToInitialState();
}

11.6 MMTimeManager — 时间管理

public class MMTimeManager : MMSingleton<MMTimeManager>
{
    static float DeltaTime { get; }
    static void SetTimeScale(float scale);
    static void Pause();
    static void Resume();
}

11.7 MMTween — 缓动系统

// 30+ 缓动曲线
public enum MMTweenType
{
    Linear, EaseInQuad, EaseOutQuad, EaseInOutQuad,
    EaseInCubic, EaseOutCubic, EaseInOutCubic,
    EaseInQuart, EaseOutQuart, EaseInOutQuart,
    EaseInElastic, EaseOutElastic, EaseInOutElastic,
    EaseInBounce, EaseOutBounce, EaseInOutBounce,
    // ...
}

11.8 其他核心模块

模块 功能
MMPropertyControllers 通过曲线/随机值动态控制 GameObject 属性
MMRadio 基于 ScriptableObject 的广播监听系统
MMSaveLoad JSON 序列化存档、PlayerPrefs、加密选项
MMSceneLoading 异步场景加载(进度条、过渡动画)
MMHelpers 数学、几何、颜色、数组、GUI 等工具函数
MMAttributes [MMInspectorGroup][MMCondition] 等编辑器特性
MMExtensions C# 类型扩展方法
MMObservable 观察者模式实现
MMUI UI 工具函数

12. MMTools Foundation 扩展

模块 功能
MMAchievements 成就系统(定义、解锁、持久化)
MMAI AI 工具(视野检测、巡逻路线)
MMAnimation 动画辅助(帧动画、动画曲线工具)
MMControls 虚拟摇杆、按钮等控制助手
MMLoot 掉落表/抽奖系统(权重概率、保底)
MMTime 计时器、倒计时工具

13. NiceVibrations 触觉反馈

13.1 概述

NiceVibrations (by Lofelt) 提供跨平台触觉反馈 API支持 iOS、Android 和游戏手柄。Feel 内置完整版。

13.2 HapticController — 静态 API

public static class HapticController
{
    // 全局控制
    static bool hapticsEnabled { get; set; }
    static float outputLevel { get; set; }     // 0-1

    // 播放
    static void Load(HapticClip clip);
    static void Play();
    static void Stop();
    static void Pause();
    static void Resume();

    // 参数修改
    static void SetAmplitude(float amplitude);
    static void SetFrequencyShift(float shift);
    static void Seek(float seconds);
    static void Loop(bool enabled);

    // 查询
    static float clipDuration { get; }
    static bool isPlaying { get; }
}

13.3 HapticPatterns — 预设模式

public enum PresetType
{
    None,
    Light, Medium, Heavy,       // 轻/中/重
    Success, Warning, Failure,  // 成功/警告/失败
    Selection,                  // 选择反馈
    Popup,                      // 弹窗反馈
    // ...约 20 个内置预设
}

HapticPatterns.PlayPreset(PresetType.Heavy);

13.4 组件

组件 功能
HapticSource MonoBehaviour 触觉源(播放/暂停/参数)
HapticReceiver 接收 Feel Feedback 触觉事件
HapticClip ScriptableObject 触觉数据(.haptic 文件)
Gamepad 游戏手柄震动(左右马达控制)
DeviceCapabilities 查询设备触觉支持

14. 第三方集成模块

14.1 Cinemachine

类型 脚本 功能
Feedback MMF_CinemachineShake 触发 Cinemachine 摄像机震动
Feedback MMF_CinemachineTargetGroup 控制目标组
Feedback MMF_CinemachineImpulse 触发冲击信号
Shaker MMCinemachineShaker Cinemachine 专用 Shaker

14.2 URP (通用渲染管线)

Feedback 功能
MMF_URPBloom Bloom 辉光
MMF_URPColorGrading 颜色分级
MMF_URPChromaticAberration 色差
MMF_URPDistortion 畸变
MMF_URPVignette 晕影

14.3 HDRP (高清渲染管线)

Feedback 功能
MMF_HDRPBloom Bloom 辉光
MMF_HDRPColorGrading 颜色分级
MMF_HDRPChromaticAberration 色差
MMF_HDRPDistortion 畸变
MMF_HDRPLensFlare 镜头光晕

14.4 PostProcessing (v2)

支持 Bloom、ChromaticAberration、ColorGrading、Distortion、MotionBlur、Vignette 等效果的 Feedback 和 Shaker。

14.5 TextMesh Pro

Feedback 功能
MMF_TMPText 改变 TMP 文本内容
MMF_TMPColor 改变 TMP 颜色
MMF_TMPFontSize 改变字体大小
MMF_TMPCharacterSpacing 字符间距
MMF_TMPLineSpacing 行间距
MMF_TMPScale 缩放文本
MMF_TMPRotation 旋转文本
MMF_TMPFloatingText 飘浮文本特效

14.6 NiceVibrations 集成

MMF_NiceVibrations — 直接在 Feedback 列表中触发触觉反馈。

14.7 UI Toolkit

Feedback 功能
MMF_UIToolkitScale 缩放 UI 元素
MMF_UIToolkitRotate 旋转 UI 元素
MMF_UIToolkitTranslate 移动 UI 元素
MMF_UIToolkitOpacity 改变透明度
MMF_UIToolkitColor 改变颜色

14.8 Visual Effect Graph

MMF_VFXGraph — 控制 VFX Graph 参数和播放。


15. Demo 场景一览

15.1 标准演示 (FeelDemos)

场景 展示内容
Barbarians 战斗角色受击/攻击反馈
Blob 软体生物弹性反馈
Bounce 弹跳物理反馈
Brass 音乐演奏反馈
CardsUI UI 卡片翻转反馈
Duck 角色控制反馈
Letters 文本/字母效果
MMProgressBar 进度条反馈动画
MMSequencer 序列系统演示
MMSoundManager 声音管理器
ParallaxUI 视差 UI 效果
Snake 贪食蛇游戏反馈
Springs 弹簧系统演示
SquashAndStretch 压缩伸展效果
Tactical 战术游戏反馈
Toaster 简单交互演示
Wheel 车轮物理反馈

15.2 URP/HDRP 演示

  • FeelDemosURP/Strike — URP 后处理反馈
  • FeelDemosHDRP — HDRP 后处理反馈

16. 与 BaseGames 架构集成方案

16.1 当前架构定位

根据 BaseGames 架构总纲(00_Architecture_Overview.md)的明确声明:

MMFeedbacks (Feel) 不再作为依赖。反馈由 FeedbackProfileSO 独立实现。

因此 MMFeedbacks 核心系统并非项目运行时依赖。BaseGames 使用自研的 FeedbackProfileSO 实现反馈编排VFX、SFX、震屏、停帧、触觉而非 MMF_Player。

16.2 实际使用的 Feel 子模块

虽然 MMFeedbacks 本身不被依赖,但 Feel 包含的部分工具模块仍有价值:

模块 状态 说明
NiceVibrations 使用中 架构文档明确引用,通过 FeedbackProfileSO.HapticIntensity 触发
MMTools/MMHelpers 📦 可选参考 数学/几何工具,但项目有自己的核心工具
MMTools/MMObjectPool 不使用 项目已有 ObjectPool (Core 层)
MMTools/MMEvents 不使用 项目已有 EventBus<T> (Core 层)
MMTools/MMSingletons 不使用 项目已有 ServiceLocator 模式
MMTools/MMLoot 📦 可选参考 掉落表系统可参考
MMFeedbacks 核心 不使用 FeedbackProfileSO 替代

16.3 FeedbackProfileSO 与 MMFeedbacks 对比

维度 FeedbackProfileSO (BaseGames) MMF_Player (Feel)
定位 轻量 SO直接函数调用 重量级编排引擎
反馈种类 5 种VFX/SFX/震屏/停帧/触觉) 74+ 种
配置方式 单个 SO 文件 Inspector 反馈列表
依赖 仅 EventBus + ObjectPool 完整 Feel 框架
代码量 ~50 行 数万行
灵活度 针对 Metroidvania 优化 通用游戏手感
性能 极简调用链 协程 + 反射 + 事件广播

16.4 NiceVibrations 集成细节

当前架构中,触觉反馈通过 FeedbackProfileSO 触发:

// FeedbackProfileSO.Play(Transform anchor)
if (HapticIntensity > 0f)
{
    // 调用 NiceVibrations API
    HapticPatterns.PlayPreset(MapIntensityToPreset(HapticIntensity));
}

建议封装适配器以隔离对 NiceVibrations 的直接依赖。

16.5 可借鉴的设计思想

虽然不直接依赖 MMFeedbacks以下设计思想值得 FeedbackProfileSO 参考:

特性 说明 建议
强度衰减 Feedback 支持距离衰减曲线 FeedbackProfileSO 可增加距离衰减支持
随机化 输出强度和持续时间可随机化 已有 PitchRange,可扩展到其他参数
通道隔离 多 Shaker 通过 Channel 区分 当多摄像机时可参考
Spring 弹簧 物理弹簧驱动的动画 受击抖动/UI 弹入可用 Spring 替代固定曲线
序列系统 按节奏编排反馈 Boss 战阶段转换表演可参考

16.6 Spring 系统独立使用建议

Feel 的 Spring 系统可以独立于 MMFeedbacks 使用。对于 BaseGames 项目中需要物理弹性动画的场景,可以直接使用 MMSpringFloat/MMSpringVector3 等类:

// 在自定义组件中独立使用 Spring
using MoreMountains.Feedbacks;

public class UIBounce : MonoBehaviour
{
    private MMSpringVector3 scaleSpring = new MMSpringVector3();

    void Awake()
    {
        scaleSpring.Damping = 0.3f;
        scaleSpring.Frequency = 8f;
        scaleSpring.SetInitialValue(Vector3.one);
    }

    public void Pop()
    {
        scaleSpring.Bump(new Vector3(0.3f, 0.3f, 0f));
    }

    void Update()
    {
        scaleSpring.UpdateSpringValue(Time.deltaTime);
        transform.localScale = scaleSpring.CurrentValue;
    }
}

注意: 如果使用 Spring确保通过适配器隔离以符合防腐层原则。


17. 性能分析与优化建议

17.1 性能特性

方面 评估
运行时开销 空闲时零开销;播放时协程 + 事件广播
GC 压力 使用协程和委托,有一定 GCPerformanceMode 可减少 Inspector 开销)
初始化 所有 Feedback 在 Awake/Start 时初始化
内存占用 取决于 Feedback 数量和引用的资源
编辑器性能 反馈列表较长时 Inspector 刷新慢(PerformanceMode 解决)

17.2 优化建议

建议 说明
PerformanceMode = true 正式构建禁用 Inspector 实时刷新
控制反馈数量 单个 Player 不超过 20 个 Feedback
使用对象池 MMF_ParticlesInstantiation 等使用内置池
避免每帧播放 使用 CooldownDuration 限制频率
按需初始化 设置 InitializationMode 为 Script 模式
距离裁剪 使用 OnlyPlayIfWithinRange 裁剪远处反馈

18. 优缺点总结

18.1 优势

优势 说明
即开即用的丰富反馈 74+ 种内置 Feedback 覆盖几乎所有需求
可视化编排 Inspector 中组合调试,策划友好
Spring 物理弹簧 自然的过冲/振荡动画,品质优于固定曲线
全平台触觉 内置 NiceVibrations 覆盖 iOS/Android/手柄
渲染管线全覆盖 URP/HDRP/Built-in 都有对应后处理反馈
时序系统完善 延迟、冷却、重复、方向、序列、概率
工具库丰富 MMTools 包含事件系统、对象池、状态机等通用工具
完整源码 所有代码可见,便于学习和魔改
持续更新 More Mountains 活跃维护

18.2 不足

不足 说明
体量庞大 完整包含数万行代码,引入大量不必要依赖
协程驱动 大量使用协程,不如 Job/Burst 高效
命名空间污染 MoreMountains.Feedbacks/MoreMountains.Tools 覆盖范围过广
工具重叠 MMTools 的事件/对象池/状态机与项目自有实现重叠
编辑器性能 大量反馈时 Inspector 卡顿
与 Corgi Engine 耦合 部分设计来自 Corgi/TopDown Engine
学习曲线 通道系统、Shaker 匹配等概念需要时间理解

18.3 技术评分

维度 评分 (1-10) 说明
功能完整度 9 74+ 反馈类型 + Spring + Sequence + 触觉,极其全面
API 设计 8 事件驱动 + 通道隔离,架构清晰
文档质量 9 官方文档详尽Demo 场景丰富
性能 6 协程 + 反射 + GC中等偏下
易用性 8 Inspector 可视化编排,上手友好
可维护性 7 源码量大,但结构清晰
与项目契合度 5 核心 MMFeedbacks 被 FeedbackProfileSO 替代,仅 NiceVibrations 有用
综合 7.4 优秀的通用 Game Feel 方案,但与 BaseGames 架构重叠较多

19. 总结与建议

19.1 总体评价

Feel v4.3 是 Unity 生态中最完善的 游戏手感工具套件,其 MMFeedbacks 系统提供了迄今最丰富的可视化反馈编排能力。然而,对于 BaseGames 这样已经自研了 FeedbackProfileSO + EventBus + ObjectPool 等基础设施的项目Feel 的核心价值主要体现在:

  1. NiceVibrations — 项目直接使用的触觉反馈 API
  2. Spring 系统 — 可独立使用的物理弹簧动画引擎
  3. 设计参考 — 通道系统、时序控制、强度衰减等思想可反哺 FeedbackProfileSO 设计

19.2 集成建议

建议 优先级 说明
保持 NiceVibrations 依赖 已在使用,确保通过适配器隔离
不引入 MMFeedbacks 运行时 维持 FeedbackProfileSO 轻量方案
考虑 Spring 独立使用 UI 弹入/受击抖动场景可用
清理 MMTools 冗余 若不使用可移除以减少编译时间
参考 MMF_FeedbackTiming 可为 FeedbackProfileSO 增加冷却/延迟/概率

19.3 扩展建议

若未来需要增强 FeedbackProfileSO 的能力,可参考 Feel 的以下设计:

// 增强版 FeedbackProfileSO 示例
public sealed class FeedbackProfileSO : ScriptableObject
{
    // --- 现有字段 ---
    public GameObject VfxPrefab;
    public AudioClip SfxClip;
    public float ShakeIntensity;
    public float HitStopDuration;
    public float HapticIntensity;

    // --- 可从 Feel 借鉴的增强 ---
    [Header("高级控制 (参考 Feel)")]
    public float CooldownDuration;                 // 冷却时间
    [Range(0, 100)] public float Chance = 100f;    // 播放概率
    public AnimationCurve DistanceFalloff;          // 距离衰减曲线
    public float MaxRange = 50f;                    // 最大有效距离
    public Vector2 ShakeIntensityRange;             // 震屏强度随机范围
}

19.4 资源管理建议

  • Feel/FeelDemos* — 可安全删除,仅供学习
  • Feel/MMFeedbacks/MMFeedbacksForThirdParty/HDRP/ — 项目使用 URP可删除 HDRP 集成
  • Feel/MMFeedbacks/MMFeedbacksForThirdParty/PostProcessing/ — v2 后处理已被 URP 内置替代
  • Feel/MMTools/Foundation/ — 根据实际使用情况保留或删除
  • Feel/NiceVibrations/ — 保留,项目运行时依赖