手感不是"最后再抛光"的那一层
把"打击感"拆开看:它是一堆有具体参数的功能。9 点偏移采样、0.2 像素阈值、渲染位置与物理位置之间的 20 毫秒。
"打击感"这个词我最不舒服的地方在于它听起来像玄学,而且被放在流程的最后一步 —— 逻辑做完了,"再来点 juice"。
Anuradhi Karunaratne 在 Game Feel: A Systematic Review 里把这件事正面顶了回来:那份综述的核心主张是 game feel 本身就是一项功能,应该在需求阶段就被要求、在实现阶段就被测试,而且需要专门投入的时间量级是"数百小时"。这不是修辞,是排期结论。
我接受这个说法,因为我自己的经验里,手感问题从来不是"特效不够",而是某个具体机制缺失。下面这些就是那些机制,以及它们可以精确到什么程度。
屏幕震动:先别抖摄像机
Vlambeer 的演讲《The Art of Screenshake》(Jan Willem Nijman,独立游戏开发者峰会 2014)里我认为最有工程含量的一条是:抖动应该作用于单个物体的偏移,而不是整个摄像机。原因是"清晰性优先" —— 摄像机一抖,玩家的准星、敌人轮廓、可交互提示全部跟着糊掉,而这些恰恰是玩家判定下一步操作的信息来源。(这场演讲我没有附链接:网上能找到的转载版本 ID 不一致,我无法确认哪一个才是原始上传,宁可只给标题。)
Karunaratne 那份综述里把射击震动拆成了可调参数,读完我印象最深的是那几个数字(文中给的是"常用起点",不是最优值):
| 参数 | 他的经验值 |
|---|---|
| 最大振幅 | 2~4 像素,按武器伤害缩放 |
| 频率 | 15~30Hz(15Hz 用于大武器) |
| 衰减 | 200~300ms 指数衰减 |
| 触发前提 | 只在真命中时触发,"没有 hit 就不要 shake" |
最后那条很值得单独抄一遍:震动是反馈,不是氛围。空挥也抖,玩家很快就会把震动当成噪声过滤掉,于是它作为一个信息通道就报废了。
静止的摄像机是假的摄像机
这条是我从 Kyle Pittman 的 Smooth Camera Shakes & Screenshots 里捡到的:一个完全静止的摄像机在 CRT 时代会显得非常假 —— 因为那个年代大多数游戏用 15Hz 渲染,摄像机每 4 帧才更新一次,本身就在微微颤动。
Pittman 因此建议加一个幅度小到"意识不到是抖动"的常驻噪声(文中举的例子是 1 像素)。这里有个反直觉的量化结论:那篇文章给的数据是,人眼能察觉的屏幕运动小到 0.2 像素 —— 所以"我把它设成 1 像素玩家肯定看不出来"这种判断是靠不住的。
同一篇文章里还有个我认为可以直接抄进渲染代码的技巧:给每个物体一个 3×3 的九点偏移网格,逐帧随机挑一个点作为采样位置去贴图。因为浮点亚像素采样在多数引擎里开销高,而这种"离散抖动"在 2D tile 上几乎免费,视觉上却接近连续偏移。
顺便,同一个噪声源不要同时喂给摄像机和物体,否则相对位移被抵消,震动看起来像没生效 —— 这条我踩过。
真正的隐藏坑:你打中的是哪一帧的位置
Michael Lutz 的 The Hidden Pitfalls Of Game Interpolation 讲了一件非常具体的事,而且给了一段我很喜欢的观察:
在快节奏射击里,玩家从看到目标到按下扳机大约 200ms,而鼠标瞄准的精度比键盘方向控制高一个数量级 —— 于是插值带来的位置偏差在这个精度下变得可见。
后果很直接:如果碰撞检测跑在物理位置上、渲染跑在插值(过去)位置上,那么在快节奏游戏里命中测试应该用渲染位置;反过来说,用物理位置做判定,玩家"瞄着打"时会觉得手感莫名其妙。
文中给的工程参数是:提前渲染大约 20ms(1~2 帧),并且按"渲染延迟 + 一帧"的窗口去收集输入。还有两条约束我认为比参数更重要:
- 插值只取平均、绝不外推 —— 一旦外推到未来,误差会指数级放大,而且外推的轨迹和它下一帧要收敛到的真实轨迹在物理上不相容。
- 插值代码必须不持有权威状态:真实状态只由物理/网络写入,插值层只读,否则玩家位移会"漂"。
顺带一条很实用的:如果对象会按事件顺序反复重置插值目标(典型场景是弹跳),用 Vector2.Reflect 而不是 Vector2.SmoothDamp —— 后者会把角度变化抹成位置偏移,弹墙的样子就错了。
音画不是两件事
最后一条来自 Nijman:那篇演讲把音效称为"手感的 50%",并指出音画绑定有窗口 —— 两个声音之间间隔超过约 120~130ms 就会失去关联,玩家开始听到"哒-哒"而不是一个动作。配套建议是给音效配和动画同样的缓动曲线。
这条对我影响很大,因为它意味着"音频是另一个人另一步的活儿"这种分工本身就是 bug 来源。Sivitor 那篇 Juicing Gameplay With Audio 给了一个具体的耦合手段:枪声的低音强度跟随射击时的屏幕震动强度 —— 也就是把两个反馈通道挂在同一个信号上,而不是各调各的。
流程上我会改什么
Karunaratne 引的是 Swink 的那套 Gameplay-First Design 循环,我觉得值得贴在墙上:
- 先定义动作的"角色"(这个技能在体验上应该是什么感觉),
- 忽略美术和音效,只做无渲染的原型去验证它 —— Swink 的说法是"用纯粹的数学和力",
- 最后才做映射:把已经成立的手感翻译成视觉和听觉。
顺序反过来的话,你会用美术去掩盖机制的问题,然后就再也找不到它了。
一个例外我认可:如果某条反馈在输入产生的那一刻就已经可见(比如拖拽时目标立刻高亮),那它可以先于机制存在。Karunaratne 用了一个挺妙的类比 —— 这类东西像"进化上更古老的脑区",它不依赖机制正确就能生效。
参考来源
- The Art of Screenshake — Jan Willem Nijman(Vlambeer,独立游戏开发者峰会 2014 演讲;转载版本 ID 不一致,故不附链接)
- Game Feel: A Systematic Review(Visual Impact, Part 1) 与 Part 2(动态与反馈) — Anuradhi Karunaratne
- Smooth Camera Shakes & Screenshots — Kyle Pittman
- The Hidden Pitfalls Of Game Interpolation (And How To Overcome Them) — Michael Lutz
- Feel Good Title Sequences Are Made, Not Born — Kyle Pittman("Juice is a bad word")
- Juicing Gameplay With Audio — Sivitor
- Juice it or lose it — Martin Jonasson & Petri Purho(2012 演讲;原幻灯片页已不可达,此处为报道页,本站抓取遇反爬)