土法炼钢兴趣小组的算法知识备份

游戏中的数学 (0) - 基础工具箱:标量数学

目录

引言

在打开 Unity 的 Mathf 或 Unreal 的 FMath 文档时,你可能会看到几十个函数。其中有一些函数是如此常用,以至于它们构成了游戏逻辑的基石。 本章不讨论复杂的向量或矩阵,只关注最基础的标量 (Scalar) 运算——即对单个浮点数的操作。 可以把这一篇看成 Unity Mathf / Unreal FMath 里常用标量函数的“中文说明书”和使用场景合集。

1. 线性插值 (Lerp)

Lerp (Linear Interpolation) 可能是游戏开发中最著名的函数。

公式

\[ Lerp(a, b, t) = a + (b - a) \times t \] 或者写作: \[ Lerp(a, b, t) = (1 - t) \times a + t \times b \]

其中: - \(a\): 起始值 (当 \(t=0\)) - \(b\): 终点值 (当 \(t=1\)) - \(t\): 进度/百分比 (通常在 0 到 1 之间)

Lerp Visual

游戏中的应用

  1. 平滑移动: 每帧将物体的位置向目标位置移动一点点。

    // 简单的平滑跟随
    currentPos = Mathf.Lerp(currentPos, targetPos, Time.deltaTime * speed);
  2. 颜色渐变: 随着血量降低,血条颜色从绿色变为红色。

    healthColor = Color.Lerp(Color.red, Color.green, healthPercent);
  3. 动画混合: 在两个动画状态之间过渡。

2. 反向插值 (InverseLerp)

如果你知道起始值 \(a\)、终点值 \(b\) 和当前值 \(v\),你想知道 \(v\) 处于 \(a\)\(b\) 之间的什么位置(即求 \(t\)),这就需要 InverseLerp

公式

\[ t = \frac{v - a}{b - a} \]

游戏中的应用

  1. 计算进度条: 玩家经验值是 500,当前等级是从 0 到 1000 经验。 progress = InverseLerp(0, 1000, 500) -> 结果是 0.5。
  2. 根据距离计算音量: 声音在 10米处最大,50米处消失。 volume = 1.0 - InverseLerp(10, 50, currentDistance)

3. 范围映射 (Remap)

这是 InverseLerpLerp 的组合拳。将一个数值从一个范围映射到另一个范围。 例如:将输入信号 (-1 到 1) 映射到 屏幕坐标 (0 到 1920)。

公式

\[ t = InverseLerp(inMin, inMax, value) \] \[ result = Lerp(outMin, outMax, t) \]

Remap Visual

代码实现 (Unity Extension)

public static float Remap(float value, float from1, float to1, float from2, float to2) {
    return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
}

游戏中的应用

4. 限制 (Clamp)

将数值限制在指定的范围内。

变体

游戏中的应用

5. 平滑步进 (SmoothStep)

Lerp 是线性的,变化率是恒定的。如果你想要“起步慢,中间快,结束慢”的效果,就需要 SmoothStep。它使用一个 S 形曲线 (Sigmoid-like) 进行插值。

公式 (Hermite 插值)

\[ t = Clamp01(t) \] \[ result = t \times t \times (3 - 2 \times t) \]

SmoothStep Curve

游戏中的应用

6. 接近 (MoveTowards)

MoveTowardsLerp 很像,但有一个关键区别:Lerp 的第三个参数是比例,而 MoveTowards 的第三个参数是最大增量 (MaxDelta)

公式

\[ result = value + sign(target - value) \times min(abs(target - value), maxDelta) \]

游戏中的应用

7. 循环与摆动 (Repeat & PingPong)

这两个函数通常用于处理时间或循环动画。

重复 (Repeat)

Repeat(t, length) 类似于取模运算 (Modulo),但对浮点数和负数处理得更好。它让数值永远保持在 [0, length] 之间。

公式

\[ result = t - floor(t / length) \times length \]

游戏中的应用

乒乓 (PingPong)

PingPong(t, length) 让数值在 0length 之间来回摆动。就像乒乓球一样,撞到边界就反弹。

公式

\[ result = length - abs(Repeat(t, length \times 2) - length) \]

游戏中的应用

总结

函数 作用 典型应用
Lerp 线性插值 (按比例) 平滑跟随、颜色渐变
InverseLerp 求比例 计算进度条、归一化数据
Remap 范围转换 数值映射、UI适配
Clamp 限制范围 血量限制、角度限制
SmoothStep S形插值 自然动画、地形平滑
MoveTowards 匀速接近 匀速移动、巡逻
Repeat 循环 滚动背景、时间循环
PingPong 来回摆动 呼吸灯、往返巡逻

掌握这些基础函数,能让你在写游戏逻辑时少写很多 if-else,代码也会更加优雅。


回到目录 | 下一篇: 三角函数入门 >


By .