# 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. [概述与设计哲学](#1-概述与设计哲学) 2. [架构总览](#2-架构总览) 3. [MMF_Player — 反馈播放器](#3-mmf_player--反馈播放器) 4. [MMF_Feedback — 反馈基类](#4-mmf_feedback--反馈基类) 5. [MMFeedbackTiming — 时序配置](#5-mmfeedbacktiming--时序配置) 6. [所有 Feedback 类型分类](#6-所有-feedback-类型分类) 7. [Shaker 系统](#7-shaker-系统) 8. [Spring 弹簧系统](#8-spring-弹簧系统) 9. [Sequencing 序列系统](#9-sequencing-序列系统) 10. [通道系统 (Channel)](#10-通道系统-channel) 11. [MMTools 核心工具库](#11-mmtools-核心工具库) 12. [MMTools Foundation 扩展](#12-mmtools-foundation-扩展) 13. [NiceVibrations 触觉反馈](#13-nicevibrations-触觉反馈) 14. [第三方集成模块](#14-第三方集成模块) 15. [Demo 场景一览](#15-demo-场景一览) 16. [与 BaseGames 架构集成方案](#16-与-basegames-架构集成方案) 17. [性能分析与优化建议](#17-性能分析与优化建议) 18. [优缺点总结](#18-优缺点总结) 19. [总结与建议](#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 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` | 反馈列表 | | `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 核心方法 ```csharp // === 播放 === 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 使用示例 ```csharp 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` | 通道模式 (`Int` 或 `MMChannel`) | | `Channel` | 整数通道 ID | | `MMChannelDefinition` | MMChannel ScriptableObject | ### 4.3 随机化 | 属性 | 说明 | |------|------| | `RandomizeOutput` | 是否随机化输出强度 | | `RandomMultiplier` | 强度随机范围 (Vector2) | | `RandomizeDuration` | 是否随机化持续时间 | | `RandomDurationMultiplier` | 时长随机范围 | ### 4.4 距离衰减 | 属性 | 说明 | |------|------| | `UseRange` | 是否启用距离范围 | | `RangeDistance` | 范围距离 | | `UseRangeFalloff` | 是否使用衰减曲线 | | `RangeFalloff` | 衰减曲线 (AnimationCurve) | ### 4.5 生命周期虚方法(子类重写) ```csharp // 核心生命周期 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 示例 ```csharp [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` | 时标模式 | **虚方法**: ```csharp 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 核心方法 ```csharp // 移动 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): ```csharp [CreateAssetMenu(menuName = "MoreMountains/Sequencer/MMSequence")] public class MMSequence : ScriptableObject { public float Length; // 序列长度(秒) public MMSequenceList OriginalSequence; // 原始序列数据 public bool Quantized; // 是否量化 public int TargetBPM; // 目标 BPM public List QuantizedSequence; // 量化后数据 public List SequenceTracks; // 轨道定义 public float EndSilenceDuration; // 末尾静默 public void SortOriginalSequence(); // 按时间排序 public void QuantizeOriginalSequence(); // 量化序列 } ``` **MMSequencer** (MonoBehaviour): ```csharp 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 — 轻量事件系统 ```csharp // 定义事件结构 public struct MyEvent { public float Value; } // 监听 MMEventManager.AddListener(OnMyEvent); // 触发 MMEventManager.TriggerEvent(new MyEvent { Value = 1f }); // 取消 MMEventManager.RemoveListener(OnMyEvent); ``` ### 11.2 MMAudio — 音频管理 | 组件 | 功能 | |------|------| | `MMSoundManager` | 全局声音管理中枢(播放、停止、淡入淡出、分组) | | `MMPlaylist` | 播放列表循环管理 | | `MMAudioAnalyzer` | 音频频谱分析 | ### 11.3 MMObjectPool — 泛型对象池 ```csharp public class MMObjectPool where T : Component { T GetPooled(); void DestroyPooled(T obj); void DestroyAll(); } public interface IMMPoolable { void OnMMPooled(); // 进入池 void OnMMUnpooled(); // 离开池 } ``` ### 11.4 MMSingletons — 单例模式 | 类 | 说明 | |----|------| | `MMSingleton` | 标准单例,场景卸载时销毁 | | `MMPersistentSingleton` | 持久单例,`DontDestroyOnLoad` | ### 11.5 MMStateMachine — 泛型状态机 ```csharp public class MMStateMachine where T : class { void ChangeState(T newState); void GoToInitialState(); } ``` ### 11.6 MMTimeManager — 时间管理 ```csharp public class MMTimeManager : MMSingleton { static float DeltaTime { get; } static void SetTimeScale(float scale); static void Pause(); static void Resume(); } ``` ### 11.7 MMTween — 缓动系统 ```csharp // 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 ```csharp 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 — 预设模式 ```csharp 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` (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` 触发: ```csharp // 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` 等类: ```csharp // 在自定义组件中独立使用 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 压力** | 使用协程和委托,有一定 GC(`PerformanceMode` 可减少 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 的以下设计: ```csharp // 增强版 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/` — 保留,项目运行时依赖