ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Unity相机抖动插件Camera-Shake集成与应用实战指南

Unity相机抖动插件Camera-Shake集成与应用实战指南 1. 项目概述与核心价值最近在做一个动作游戏需要给主角的重击和爆炸场景加点料让打击感更足。我第一时间就想到了给相机加个抖动效果毕竟这是提升玩家沉浸感最简单直接的手段之一。自己手写一个也不是不行但时间成本高效果调起来也麻烦。于是我开始在GitHub和Unity Asset Store上找现成的方案最终锁定了这个名为“Camera-Shake”的开源项目。它完全免费代码清晰功能也够用非常适合快速集成和二次开发。简单来说Camera-Shake就是一个专门为Unity引擎设计的、用来模拟各种相机抖动效果的插件。无论是角色受伤、武器开火、车辆撞击还是场景中的爆炸你都可以通过它来快速实现逼真的镜头反馈。它的核心价值在于“开箱即用”和“高度可定制”。你不需要从零开始研究如何用数学曲线去模拟震动它已经封装好了几种经典的抖动模式如冲击波、持续震动、随机抖动等并且提供了非常直观的参数面板让你在Inspector窗口里动动滑块就能调出想要的感觉。对于独立开发者和小团队来说能省下大量重复造轮子的时间。这个项目在GitHub上可以找到作者维护得还算积极社区里也有不少讨论。接下来我就结合自己从下载、导入、配置到实际应用的全过程给你一份详细的指南。我会重点讲清楚每个步骤的意图、可能遇到的坑以及如何根据你的游戏类型调整参数让它真正为你所用。2. 环境准备与项目获取在开始之前确保你的开发环境是准备好的。我使用的是Unity 2021.3 LTS版本这个长期支持版本比较稳定插件兼容性也最好。Camera-Shake项目本身对Unity版本要求并不苛刻理论上2018.4以上的版本都可以运行但为了避开一些潜在的包管理或API差异建议使用2020.3或2021.3这些LTS版本。2.1 获取项目源码Camera-Shake是一个托管在GitHub上的开源项目。获取它的方式主要有两种我个人更推荐第一种因为它能让你更好地融入Unity的包管理生态方便后续更新。方法一通过Unity的Package Manager安装推荐这是最“现代”也是最干净的方式。Unity的Package Manager支持直接从Git URL添加包。在Unity编辑器中打开Window Package Manager。点击窗口左上角的“”按钮选择“Add package from git URL...”。在弹出的输入框中填入Camera-Shake项目的Git仓库地址。通常格式是https://github.com/作者名/仓库名.git。你需要去该项目的GitHub页面找到准确的地址。例如假设地址是https://github.com/JohnDoe/CameraShake.git。点击“Add”。Unity会自动从GitHub克隆仓库并将其作为一个本地包导入到你的项目中。你可以在Package Manager的“My Registries”或“In Project”列表中看到它。注意使用此方法要求项目仓库必须包含一个有效的package.json文件并且结构符合Unity UPM包规范。如果原项目不是以UPM包形式发布的你可能需要手动创建一个package.json或者采用第二种方法。方法二直接下载并导入UnityPackage或源码如果项目提供了.unitypackage文件或者上述Git URL方法不奏效你可以直接下载源码。访问项目的GitHub页面找到“Releases”标签页看是否有打包好的.unitypackage文件可供下载。这是最省事的方式。如果没有则点击绿色的“Code”按钮选择“Download ZIP”将整个项目源码下载到本地。在你的Unity项目中你可以直接将下载的.unitypackage文件拖入Project窗口进行导入。或者解压ZIP文件将其中的Assets、Packages如果有等文件夹复制到你项目的对应目录下。实操心得 我最初尝试了Git URL的方式但发现那个仓库的package.json配置有点问题导致依赖解析失败。于是我转而下载了ZIP包。我的做法是在项目的Assets文件夹下创建一个名为ThirdParty或Plugins的文件夹然后把解压后的CameraShake源码文件夹整个拖进去。这样能保持项目结构的清晰未来如果需要移除直接删除这个文件夹即可不会污染其他资源。2.2 导入后的初步检查无论用哪种方式导入成功后你都需要在Unity编辑器里进行初步检查确保没有报错。检查Console窗口导入后第一时间查看Unity编辑器底部的Console窗口。理想情况下应该是干净的或者只有一些无害的信息提示。如果出现红色错误最常见的原因是脚本编译错误比如命名空间冲突、使用了新版本Unity已废弃的API等。你需要根据错误信息进行修改。在Project窗口中定位使用搜索框搜索“CameraShake”或相关的主要类名如“CameraShaker”。如果能找到对应的C#脚本文件说明源码导入成功。检查示例场景很多优秀的开源项目都会提供示例场景Example Scenes。在Project窗口中找找有没有名为“Examples”、“Demo”或“Scenes”的文件夹打开里面的场景文件。这是最快了解插件功能的方式。运行示例场景看看效果是否符合预期。3. 核心组件解析与工作原理成功导入后先别急着用。花点时间理解它的核心组件和工作原理能让你在后面配置和调试时事半功倍。Camera-Shake项目的核心通常围绕两个部分震动发生器Shake Source和震动控制器Camera Shaker。3.1 核心类与职责CameraShaker 组件 这是需要挂载在你场景主相机或任何你想让其抖动的相机上的组件。它是震动的“接收者”和“执行者”。它的主要职责是管理震动实例接收来自各个震动源的震动请求并管理它们的生命周期开始、持续、衰减、结束。混合震动当多个震动事件同时发生时比如同时受到爆炸冲击和连续射击的后坐力它能将这些震动效果叠加混合计算出相机最终的位置和旋转偏移。控制全局属性比如震动的缩放比例Scale你可以通过它全局减弱或增强所有震动效果这在游戏暂停或播放过场动画时非常有用。震动源Shake Sources 这是一系列脚本或类用于定义一种特定类型的震动。项目通常会提供几种预设BounceShake冲击震动模拟一次性的冲击如爆炸。震动强度会迅速达到峰值然后衰减至零。你需要定义衰减的曲线通常是指数衰减。PerlinShake柏林噪声震动利用柏林噪声生成平滑、随机的震动非常适合模拟地震、发动机怠速等持续且自然的抖动。PunchShake冲击拳震动类似于Bounce但方向性更强常用于近战攻击命中时的屏幕定向晃动。SustainShake持续震动在指定时间内维持一个相对稳定的震动强度然后停止或衰减适合模拟持续的后坐力。 这些震动源本质上都是一组参数强度、频率、衰减时间、噪声种子等的封装。它们不直接修改相机而是生成一个“震动指令”发送给CameraShaker。3.2 震动的工作流程理解数据流很重要触发在你的游戏逻辑中例如在子弹命中或炸弹爆炸的函数里你创建或获取一个震动源实例并设置好参数比如magnitude2.0f, frequency10f, duration0.5f。发射调用这个震动源的一个方法通常是Shake()或StartShake()并将场景中的CameraShaker实例传递给它。处理CameraShaker将这个震动源添加到其内部的管理列表中。在每一帧的LateUpdate确保在相机常规移动计算之后中CameraShaker会遍历所有活跃的震动源。采样与叠加对于每个活跃的震动源根据当前时间和该震动源的参数采样计算出这一帧相机应有的位置偏移Position Shake和旋转偏移Rotation Shake。应用将所有震动源计算出的偏移量叠加起来最后应用到相机Transform的本地位置和旋转上。注意它通常是在相机的本地空间进行偏移这样能确保震动方向不受相机自身旋转的影响。注意事项性能考量每个活跃的震动源都需要每帧进行计算。虽然单个消耗极小但如果你的游戏同时触发几十个震动比如弹幕游戏也需要留意CPU开销。好的实践是对于大量、短促的震动如大量小口径子弹命中可以考虑进行合并或降低其采样频率。与CinemaMachine兼容如果你使用了强大的CinemaMachine来管理相机直接修改相机Transform可能会冲突。高级的Camera-Shake实现会提供与CinemaMachine的集成方式例如通过修改CinemachineImpulseSource或作为CinemachineVirtualCamera的噪音组件来工作。在导入时要留意文档或示例中是否有相关说明。4. 基础配置与快速上手理论说完了我们动手把它用起来。目标是在场景中实现一个按下空格键相机就发生一次爆炸冲击的效果。4.1 场景搭建与组件挂载创建一个新的Unity场景或使用现有场景。确保场景中有一个摄像机Main Camera。如果使用URP/HDRP确保它是基础摄像机或Stack中的主摄像机。在Hierarchy窗口中选中Main Camera在Inspector窗口中点击“Add Component”。搜索并添加“CameraShaker”组件。添加后你应该能看到类似下图的Inspector面板里面有一些可配置的参数Shake Scale全局震动缩放默认为1。如果你想临时关闭所有震动可以将其设为0。Default Shake Type可能有一个下拉菜单让你选择默认的震动类型如果组件支持预设。Smoothing平滑参数用于消除震动停止时的突然跳变让停止更自然。4.2 创建并触发一个基础震动现在我们写一个简单的测试脚本。在Project窗口中右键创建一个新的C#脚本命名为TestCameraShake。双击打开脚本编写如下代码using UnityEngine; // 引入Camera-Shake的命名空间具体名称需要根据实际项目代码确定 // 例如可能是using CameraShake; 或 using DG.CameraShake; (如果作者是Demigiant) // 你需要查看源码中的命名空间来确认 using YourCameraShakeNamespace; public class TestCameraShake : MonoBehaviour { // 引用挂载在相机上的CameraShaker组件 public CameraShaker cameraShaker; // 可调节的震动参数方便在Inspector中调试 public float magnitude 2.0f; // 震动强度 public float roughness 10.0f; // 粗糙度/频率值越大震动越快越细碎 public float fadeInTime 0.1f; // 震动淡入时间 public float fadeOutTime 0.5f; // 震动淡出时间 void Update() { // 当按下空格键时触发震动 if (Input.GetKeyDown(KeyCode.Space)) { TriggerShake(); } } void TriggerShake() { // 安全检查 if (cameraShaker null) { Debug.LogError(CameraShaker reference is not set!); return; } // 方法一如果CameraShaker组件提供了简便的静态方法或实例方法 // cameraShaker.ShakeOnce(magnitude, roughness, fadeInTime, fadeOutTime); // 方法二更通用的方式创建一个震动实例并传递参数 // 这里以BounceShake为例实际类名请参考源码 var shakeInstance new BounceShake( new Displacement(Vector3.zero, new Vector3(magnitude, magnitude, magnitude)), // 位置和旋转强度 roughness, fadeInTime, fadeOutTime ); // 将震动实例传递给CameraShaker cameraShaker.RegisterShake(shakeInstance); Debug.Log(Camera shake triggered!); } }保存脚本。回到Unity编辑器将TestCameraShake脚本拖拽到场景中的任意一个GameObject上比如一个空物体或玩家角色。在Inspector中你会看到脚本组件。将Hierarchy中的Main Camera拖拽到脚本的“Camera Shaker”字段上进行赋值。运行游戏。按下空格键你应该能看到相机产生一次抖动。参数调试心得magnitude强度这是最直观的参数。对于爆炸可以从3.0开始试对于手枪后坐力0.5可能就够了。注意它可能是一个Vector3分别控制X、Y、Z轴的强度这样你可以做出水平震动强、垂直震动弱的效果。roughness粗糙度/频率这个参数控制震动“快慢”。值太低如1.0震动会像慢速摇晃值太高如25.0震动会非常细碎、快速像高频振动。对于爆炸一个中等偏高的值如15比较合适。fadeInTime和fadeOutTime淡入淡出时间让震动的开始和结束不那么突兀。通常fadeInTime很短0.05-0.1秒让震动立刻开始fadeOutTime则决定了震动尾巴的长度爆炸可以设为0.3-0.6秒营造能量消散的感觉。5. 高级配置与实战应用基础震动实现了但要让它在游戏中真正“活”起来还需要更精细的配置和场景化的应用。5.1 定义多种震动预设在真实项目中你不会每次触发震动都去new一个实例并填一堆参数。最佳实践是创建可复用的震动预设Preset或配置文件。方法创建ScriptableObject配置资产这是Unity中管理可配置数据的优雅方式。创建一个用于存储震动参数的类并使其继承自ScriptableObject。例如ShakePreset.csusing UnityEngine; [CreateAssetMenu(fileName NewShakePreset, menuName CameraShake/Shake Preset)] public class ShakePreset : ScriptableObject { public enum ShakeType { Bounce, Perlin, Punch, Sustain } public ShakeType shakeType ShakeType.Bounce; public Vector3 positionStrength Vector3.one; public Vector3 rotationStrength Vector3.one; public float frequency 10f; public float attackTime 0.1f; public float sustainTime 0f; // 仅Sustain类型有效 public float decayTime 0.5f; public AnimationCurve attenuationCurve AnimationCurve.EaseInOut(0,1,1,0); // 衰减曲线 }在Project窗口中右键选择Create CameraShake Shake Preset创建一个预设资产比如ExplosionShake、GunFireShake。在你的震动管理脚本或武器脚本中声明一个ShakePreset类型的公共字段并将创建好的资产拖拽上去。触发震动时读取这个预设资产的参数来构造震动实例。这样做的好处是策划或美术同学可以在不接触代码的情况下在编辑器里调整各种震动效果并且所有用到同一震动的地方都能同步更新。5.2 场景化应用案例让我们看几个具体的游戏场景如何应用Camera-Shake。案例一第一人称射击武器后坐力对于自动武器我们需要的不是单次震动而是一个由若干次短促震动组成的序列。单发震动每次开枪时触发一个短促的PunchShake主要向上-Y轴和略微向后-Z轴震动模拟枪口上跳。连发叠加在自动开火模式下每次触发的震动会与上一次的震动残留叠加。要特别注意roughness和decayTime的设置。decayTime不宜过长否则连发时震动会累积到失控的程度。通常单发衰减时间设置在0.1-0.2秒。相机复位有些插件会提供“弹性复位”功能即在震动结束后相机不是瞬间回到原点而是像弹簧一样慢慢拉回这能进一步增强真实感。检查你的Camera-Shake组件是否有类似Elasticity或Recovery Speed的参数。案例二角色受伤与死亡受击震动当角色被击中时根据伤害来源的方向触发一个方向性的PunchShake。例如从左侧被击中相机可以向右轻微平移和旋转。死亡震动角色死亡时可以触发一个更强烈、持续时间稍长的BounceShake并结合屏幕渐红、慢动作等效果增强表现力。震动差异化轻伤和重伤、普通攻击和致命攻击的震动强度和模式应有明显区别。这可以通过定义不同的ShakePreset来实现。案例三环境交互与爆炸距离衰减这是爆炸震动最关键的细节。离爆心越近震动越强。你需要在触发震动的代码中计算距离。float distance Vector3.Distance(explosionPos, cameraPos); float attenuation Mathf.Clamp01(1 - distance / maxShakeRadius); // 线性衰减 // 或者使用更真实的平方反比衰减 // float attenuation 1 / (1 distance); float finalMagnitude baseMagnitude * attenuation;冲击波传递大型爆炸的震动不是瞬间到达的可以加入一个微小的延迟模拟冲击波传播的时间除非是科幻题材的瞬时能量武器。多重频率一个真实的爆炸震动可能包含多种频率成分。初始是低频高幅的冲击BounceShake随后可能跟随一些高频的碎片震动PerlinShake。可以考虑顺序触发两个不同参数的震动实例。5.3 性能优化与调试技巧当震动效果多起来后就需要关注性能和调试了。性能优化点对象池频繁创建和销毁震动实例会产生GC垃圾回收压力。可以建立一个简单的对象池来复用BounceShake,PerlinShake等实例。距离裁剪对于远离相机、屏幕外或影响极小的震动可以直接不触发或触发一个强度为0的实例。降低更新频率对于持续性的、不重要的环境震动如远处隐约的地震可以不用每帧更新每2-3帧更新一次也能接受。强度累加上限设置一个全局的最大震动强度上限防止多个震动意外叠加导致相机飞出天际。编辑器内调试技巧可视化调试可以编写一个简单的编辑器脚本在Scene视图中用Gizmos绘制出当前震动的方向和强度向量或者显示每个活跃震动源的剩余时间和强度。参数热更将CameraShaker的关键参数如全局缩放Shake Scale暴露给一个简单的UI滑块或Unity的Remote调试工具在游戏运行时实时调整快速找到最佳感觉。帧冻结分析在震动触发的瞬间使用Unity的帧调试器Frame Debugger或性能分析器Profiler查看CameraShaker的LateUpdate耗时确保其效率。6. 常见问题排查与解决方案实录在实际集成和使用过程中你几乎一定会遇到下面这些问题。我把它们和我的解决方案记录下来希望能帮你快速排雷。6.1 导入后编译错误问题现象可能原因解决方案导入后Console出现大量红色CSxxxx编译错误。1.命名空间冲突插件中的类名与你项目中的类名重复。2.API不兼容插件使用了旧版Unity的API而你的项目版本较新该API已废弃或移除。3.依赖缺失插件依赖其他库如DOTween、UniRx但你的项目没有。1. 检查错误信息。如果是重复类名可以考虑修改插件源码的命名空间较麻烦或联系作者。2. 对于API废弃警告可以尝试按照提示替换为新API。对于移除的错误可能需要寻找该插件的更新版本或自行修改源码适配。3. 查看插件的README或文档安装其所需的依赖包。我遇到的情况我导入后遇到了一个关于[System.Obsolete]的警告提示某个方法过时了。我按照警告信息找到了源码中使用UnityEngine.Random.某方法的地方将其替换为新的UnityEngine.Random.Range()方法警告就消失了。对于开源项目小修小补是常态。6.2 运行时无效果或效果异常问题现象可能原因解决方案按下按键日志显示触发了但相机毫无反应。1.CameraShaker引用为空测试脚本中的public CameraShaker cameraShaker字段没有在Inspector中赋值。2.震动强度为0传入的magnitude参数为0或极小。3.相机有其他组件覆盖例如CinemaMachine、其他相机控制脚本在LateUpdate中覆盖了CameraShaker对Transform的修改。1. 检查Inspector确保引用已正确拖拽赋值。2. 在触发代码后打印magnitude等参数的值确认其非零。3. 检查脚本执行顺序确保CameraShaker在LateUpdate中最后执行。或者尝试暂时禁用其他相机控制脚本。震动效果过于剧烈或奇怪相机乱飞。1.参数值不合理magnitude或roughness值设得太大。2.叠加失控短时间内触发了大量震动且衰减时间decayTime设置过长导致强度累加。3.本地空间与世界空间混淆插件设计是在本地空间震动但你的相机旋转复杂导致偏移方向错误。1. 从很小的参数开始调试如magnitude0.1逐步增加。2. 为同类震动设置一个冷却时间或最大叠加数量。缩短decayTime。3. 查阅插件文档确认其工作空间。如果是本地空间确保相机的父物体没有异常的旋转或缩放。震动停止时相机没有回到原位有偏移。1.平滑Smoothing参数问题平滑算法可能导致最终位置无法精确归零。2.浮点数精度误差计算中的微小误差累积。3.其他脚本干扰在震动结束后其他脚本又修改了相机位置。1. 尝试调整或禁用CameraShaker上的平滑参数。2. 可以在震动完全停止后例如通过协程等待fadeOutTime0.1f手动将相机的本地位置和旋转重置为Vector3.zero和Quaternion.identity。3. 使用Debug模式在震动结束后检查相机Transform值的变化。6.3 与其他系统如CinemaMachine的集成问题这是最常遇到的进阶问题。很多项目都会用CinemaMachine来处理相机的复杂运镜。问题添加了CameraShaker后CinemaMachine控制的相机完全不抖或者抖动一下后立刻被Cinemachine拉回原位。原因CinemaMachine在每帧的LateUpdate中会根据自己的规则如Follow、LookAt完全控制虚拟相机Virtual Camera的最终状态。普通的CameraShaker直接修改Camera.main的Transform这个修改会被随后执行的CinemaMachine覆盖掉。解决方案 通常有两种主流集成方式使用CinemaMachine自带的噪音组件Noise CinemaMachine的Virtual Camera自带CinemachineBasicMultiChannelPerlin或CinemachineCollisionImpulseSource等组件来制造抖动。如果你的Camera-Shake插件提供了对应的CinemachineExtension可以直接使用。如果没有你可能需要将Camera-Shake的逻辑移植到创建一个自定义的CinemachineExtension中这需要较深的CinemaMachine API知识。将CameraShaker作为Impulse Source推荐如果插件支持 这是更优雅的方式。CinemaMachine有一个Impulse脉冲系统。你可以让你现有的震动脚本如BounceShake成为一个CinemachineImpulseSource。在触发震动时调用GenerateImpulse()方法。在需要接收震动的CinemachineVirtualCamera上添加CinemachineImpulseListener组件。 这样Camera-Shake就变成了一个“脉冲发生器”而CinemaMachine负责接收这个脉冲并应用到自己管理的相机上完美兼容。实操步骤假设插件不支持需要自己适配// 在你的震动触发脚本中 using Cinemachine; public class MyShakeSource : MonoBehaviour, IShakeTrigger { public CinemachineImpulseSource impulseSource; public float impulseForce 1f; void Start() { if (impulseSource null) impulseSource GetComponentCinemachineImpulseSource(); } public void TriggerShake() { if (impulseSource ! null) { // 设置脉冲的原始速度决定震动方向和强度 impulseSource.m_DefaultVelocity transform.forward * impulseForce; // 生成脉冲 impulseSource.GenerateImpulse(); } else { // 回退到原生的CameraShaker逻辑 FallbackToLegacyShake(); } } // ... 其他代码 }然后在你的Virtual Camera上添加CinemachineImpulseListener组件并调整其增益Gain等参数。我的选择我检查了使用的Camera-Shake插件它没有内置的CinemaMachine支持。但由于我的项目相机逻辑不复杂我暂时采用了“确保执行顺序”的土办法让CameraShaker脚本的LateUpdate在所有其他相机控制脚本之后执行在Script Execution Order中设置并小心控制震动强度避免冲突。对于复杂项目花时间实现Impulse Source集成是更一劳永逸的方案。7. 参数调优心得与个性化扩展调参是让震动效果出彩的关键这没有标准答案全靠感觉和反复测试。这里分享一些我的调优心得。7.1 参数调优经验表震动类型应用场景强度 (Magnitude)频率 (Roughness/Freq)衰减 (Decay)额外技巧爆炸 (Bounce)手榴弹、火箭筒、大型撞击3.0 - 8.012 - 200.4s - 1.0s结合屏幕泛白Post-processing Bloom和短时间慢动作Time.timeScale。枪械后坐力 (Punch)手枪、步枪、霰弹枪开火0.3 - 2.015 - 300.08s - 0.2s方向很重要步枪通常向上0,1,0霰弹枪可加随机水平分量。连发时衰减要短。持续震动 (Sustain/Perlin)地震、发动机、角色濒死0.5 - 2.0 (持续)5 - 15N/A (或很长)使用柏林噪声让震动更自然。可以随时间缓慢改变magnitude来模拟震级变化。受伤反馈 (Punch)角色被攻击1.0 - 3.08 - 150.2s - 0.5s震动方向应与攻击来源方向相关。可配合屏幕边缘泛红Vignette。环境互动脚步声巨兽、开门、落石0.1 - 1.05 - 100.1s - 0.3s强度要轻避免干扰玩家操作。不同材质地面可配不同强度。一个实用技巧使用AnimationCurve很多高级的震动系统允许你传入一个AnimationCurve来控制震动强度随时间的变化。这比简单的淡入淡出强大得多。对于爆炸你可以创建一个快速上升、然后呈指数下降的曲线。对于心跳可以创建一个有规律的正弦波式曲线。对于不平衡的震动如跛行可以创建一个左右强度不对称的曲线。 如果你使用的Camera-Shake插件支持强烈建议用AnimationCurve替代简单的fadeOutTime它能创造出更细腻的动态。7.2 个性化功能扩展开源项目的魅力在于你可以按需修改。这里有几个扩展思路方向性震动增强 基础的震动可能只在世界空间或相机本地空间均匀抖动。你可以修改源码让震动源接受一个direction参数。这样当角色从左侧被击中时你可以生成一个主要向右即Vector3.right的震动向量使反馈更具指向性。物理交互震动 让震动与物理引擎结合。例如当游戏中的 rigidbody 物体碰撞时根据碰撞的相对速度来计算震动的强度。void OnCollisionEnter(Collision collision) { float impactForce collision.relativeVelocity.magnitude; float shakeMagnitude Mathf.Clamp(impactForce * 0.1f, 0.5f, 5.0f); cameraShaker.ShakeOnce(shakeMagnitude, 15f, 0.05f, 0.3f); }音频驱动震动 让震动的节奏和强度与游戏音效或背景音乐的某些频率绑定。这需要解析音频数据如使用Unity的AudioSource.GetOutputData提取低频部分的振幅来驱动震动的magnitude可以创造出非常带感的节奏震动效果。UI震动反馈 震动不一定只用于相机。你可以将同样的逻辑稍加修改应用到UI元素上。例如当玩家获得重要道具时让图标轻微抖动当按钮被点击时给按钮一个微小的弹性动画。这只需要将震动偏移量应用到UI RectTransform的anchoredPosition上即可。最后记住一点少即是多。相机震动是调味剂不是主菜。过度使用或使用不当的震动会让玩家感到晕眩和烦躁。始终以玩家的舒适度为第一考量在关键时刻给予恰到好处的反馈才能最大化它的价值。我自己的习惯是在开发时频繁开关震动效果以确保没有它游戏依然可玩有了它体验才真正升华。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进