摘要:本文聚焦「游戏中的曲线艺术」,梳理核心概念、关键方法与落地实践。
[!TIP] > “God does not build in straight lines.” (上帝不造直线) — Prometheus 在游戏开发中,直线通常代表着机械与僵硬,而曲线则赋予了生命、动感与平衡。本文档旨在系统性地梳理游戏开发中涉及的各类“曲线”,从微观的动画插值到宏观的数值成长。
1. 🌊 缓动函数 (Easing Functions) - 赋予运动以质感
最基础的曲线,用于描述一个数值如何从 A 变化到 B。1.1 📏 线性 (Linear) vs 〰️ 非线性
- Linear (
t): 匀速运动。感觉机械、无聊。 - Ease In (
t^2): 加速。模拟重力下落,或车辆启动。 - Ease Out (
1 - (1-t)^2): 减速。模拟摩擦力停止,最常用的 UI 动画曲线。 - Ease In Out: 先加速后减速。模拟生物的自然运动。
1.2 🧮 常用公式 (Math)
1.4 ⚡ 速查表 (Cheat Sheet) - 哪种情况用哪种?
In vs Out vs InOut:
- 🚀 In: 从 0 加速。适合“进入视野”或“开始运动”。(如:火箭升空)
- 🛑 Out: 减速到 0。适合“停在某处”或“进入待机”。(如:UI 弹窗停在屏幕中间)
- 🔄 InOut: 先加速后减速。适合“从 A 移动到 B”。(如:摄像机运镜)
2. ✒️ 贝塞尔曲线 (Bezier Curves) - 路径与轨迹
用于定义复杂的路径,如导弹轨迹、赛道形状或 UI 连线。2.1 原理
贝塞尔曲线本质上是“线性插值的线性插值” (Lerp of Lerps)。- 二阶 (Quadratic): 需要 3 个点 (起点 P0, 控制点 P1, 终点 P2)。
- 先在 P0-P1 间 Lerp 出 A,在 P1-P2 间 Lerp 出 B。
- 再在 A-B 间 Lerp 出最终点。
- 三阶 (Cubic): 需要 4 个点。Unity 的
AnimationCurve内部就是分段的三阶贝塞尔。
2.2 代码实现
3. 📊 数值成长曲线 (Gameplay Progression Curves)
用于 RPG 升级、经济膨胀或难度控制。3.1 🚀 幂函数 (Power Curve)
- 应用: 升级所需经验值。
- 特点: 早期平缓,后期陡峭。让玩家前期快速升级获得爽感,后期升级变慢延长游戏寿命。
3.2 🛡️ 对数函数 (Logarithmic Curve)
- 应用: 护甲减伤公式 (Diminishing Returns)。
DamageReduction = Armor / (Armor + Constant)
- 特点: 收益递减。防止玩家堆叠单一属性导致无敌。
3.3 🪜 阶梯函数 (Step Function)
- 应用: 装备解锁、技能质变。
- 特点: 只有达到特定等级,能力才会有跃升。
4. 🎮 Unity 中的 AnimationCurve
Unity 内置的AnimationCurve 是极其强大的工具,不仅用于动画,还可用于逻辑配置。
4.1 🎯 技巧:归一化采样
不要在 Curve 里填具体数值 (如 0 到 1000 伤害)。- 做法: Curve 的 X 和 Y 都保持在 0-1 区间。
- 代码:
float damage = maxDamage * curve.Evaluate(currentLevel / maxLevel); - 优点: 策划调整数值上限时,不需要重画曲线。
4.2 🎲 技巧:作为概率分布
可以用 Curve 来模拟非均匀随机分布。- X 轴: 随机数 (0-1)。
- Y 轴: 实际输出值。
- 形状: 如果曲线是“S”型,那么输出值会集中在中间;如果曲线是“U”型,输出值集中在两端。
5. 🛠️ 塑形函数 (Shaping Functions)
在 Shader 和程序化生成中,我们需要更高级的数学来“重塑”信号。5.1 🗺️ Remap (重映射)
将一个区间的值映射到另一个区间。5.2 🌫️ SmoothStep
比 Lerp 更平滑的插值,两端斜率为 0。常用于地形混合、纹理边缘处理。5.3 🏓 PingPong
让数值在 0 和 1 之间往复运动。Mathf.PingPong(Time.time, 1f)
6. 📚 扩展阅读
- The Book of Shaders: Shaping Functions - 必读,图形学中的曲线圣经。
- GDC: Math for Game Developers