lerp
最后同步日期:2026-04-15 | Godot 官方原文 — lerp
lerp
定义
lerp() 是"线性插值"(Linear Interpolation 的缩写)。它的作用非常简单:在两个数值之间,按照你给的比例,算出中间的某个值。
打个比方:想象你在调音量旋钮。旋钮从最左(0)拧到最右(10),当你拧到一半的时候,音量就是 5。lerp(0, 10, 0.5) 就是在说:"从 0 到 10 的路上,走到 50% 的位置是多少?"答案就是 5。
再比如,lerp(100, 200, 0.0) 返回 100(还在起点),lerp(100, 200, 1.0) 返回 200(已经到终点),lerp(100, 200, 0.3) 返回 130(走了 30% 的路)。
为什么说它是游戏开发中用得最多的函数之一?
因为几乎所有的"平滑过渡"效果都需要它:角色平滑移动、血条渐变、颜色渐变、相机跟随、透明度淡入淡出……只要你想让一个值"慢慢地"变成另一个值,第一个想到的就应该是在 _process() 里用 lerp()。
函数签名
public static float Lerp(float from, float to, float weight)func lerp(from: float, to: float, weight: float) -> float参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
from | float | 是 | 起始值。当 weight 为 0 时,返回此值 |
to | float | 是 | 目标值。当 weight 为 1 时,返回此值 |
weight | float | 是 | 插值权重,也叫"混合比例"。0.0 = 完全是 from,1.0 = 完全是 to,0.5 = 正中间 |
返回值
float -- 计算公式为 from + (to - from) * weight。
简单理解:weight 决定了结果更靠近 from 还是 to。weight 为 0 就在 from,为 1 就在 to,为 0.25 就是靠近 from 四分之一的位置。
代码示例
基础用法:计算中间值
using Godot;
public partial class LerpExample : Node
{
public override void _Ready()
{
// 在 0 和 100 之间取 50% 的位置
float result1 = Mathf.Lerp(0f, 100f, 0.5f);
GD.Print(result1); // 运行结果: 50
// 在 10 和 20 之间取 30% 的位置
float result2 = Mathf.Lerp(10f, 20f, 0.3f);
GD.Print(result2); // 运行结果: 13
// weight = 0,返回起始值
float result3 = Mathf.Lerp(5f, 15f, 0.0f);
GD.Print(result3); // 运行结果: 5
// weight = 1,返回目标值
float result4 = Mathf.Lerp(5f, 15f, 1.0f);
GD.Print(result4); // 运行结果: 15
}
}func _ready():
# 在 0 和 100 之间取 50% 的位置
var result1 = lerp(0.0, 100.0, 0.5)
print(result1) # 运行结果: 50.0
# 在 10 和 20 之间取 30% 的位置
var result2 = lerp(10.0, 20.0, 0.3)
print(result2) # 运行结果: 13.0
# weight = 0,返回起始值
var result3 = lerp(5.0, 15.0, 0.0)
print(result3) # 运行结果: 5.0
# weight = 1,返回目标值
var result4 = lerp(5.0, 15.0, 1.0)
print(result4) # 运行结果: 15.0实际场景:平滑移动角色到目标位置
using Godot;
public partial class SmoothMover : Node2D
{
// 导出属性:目标位置
[Export] public Vector2 ExTargetPosition = new Vector2(400f, 300f);
// 导出属性:平滑系数(每帧靠近目标的比例)
[Export] public float ExSmoothFactor = 0.1f;
public override void _Process(double delta)
{
// 每帧向目标位置靠近 10%
// 这种写法的特点:越接近目标移动越慢,产生"减速停靠"的效果
Position = Position.Lerp(ExTargetPosition, ExSmoothFactor);
}
}extends Node2D
# 导出属性:目标位置
@export var target_position: Vector2 = Vector2(400.0, 300.0)
# 导出属性:平滑系数(每帧靠近目标的比例)
@export var smooth_factor: float = 0.1
func _process(delta):
# 每帧向目标位置靠近 10%
# 这种写法的特点:越接近目标移动越慢,产生"减速停靠"的效果
position = position.lerp(target_position, smooth_factor)进阶用法:渐变透明度与颜色过渡
using Godot;
public partial class FadeEffect : CanvasGroup
{
// 导出属性:淡入速度
[Export] public float ExFadeSpeed = 2.0f;
// 内部变量:是否正在淡入
private bool _isFadingIn = false;
public override void _Ready()
{
// 初始完全透明
Modulate = new Color(1f, 1f, 1f, 0f);
_isFadingIn = true;
}
public override void _Process(double delta)
{
if (_isFadingIn)
{
// 将透明度从当前值向 1.0(完全不透明)插值
float alpha = Mathf.Lerp(Modulate.A, 1.0f, ExFadeSpeed * (float)delta);
Modulate = new Color(Modulate.R, Modulate.G, Modulate.B, alpha);
// 接近完全透明时,直接设为 1.0
if (Mathf.IsEqualApprox(alpha, 1.0f))
{
Modulate = new Color(Modulate.R, Modulate.G, Modulate.B, 1.0f);
_isFadingIn = false;
GD.Print("淡入完成");
}
}
}
}extends CanvasGroup
# 导出属性:淡入速度
@export var fade_speed: float = 2.0
# 内部变量:是否正在淡入
var _is_fading_in: bool = false
func _ready():
# 初始完全透明
modulate = Color(1.0, 1.0, 1.0, 0.0)
_is_fading_in = true
func _process(delta):
if _is_fading_in:
# 将透明度从当前值向 1.0(完全不透明)插值
var alpha = lerp(modulate.a, 1.0, fade_speed * delta)
modulate = Color(modulate.r, modulate.g, modulate.b, alpha)
# 接近完全透明时,直接设为 1.0
if is_equal_approx(alpha, 1.0):
modulate = Color(modulate.r, modulate.g, modulate.b, 1.0)
_is_fading_in = false
print("淡入完成")注意事项
weight的值不限于 0~1:超出这个范围时,结果会越过起点或终点。例如lerp(0, 100, 1.5)返回150,lerp(0, 100, -0.5)返回-50。如果你需要结果严格限制在from和to之间,请在外层套用Mathf.Clamp()/clampf()。"帧率无关"的平滑移动写法:用
lerp(current, target, speed * delta)这种方式做平滑移动时,结果是帧率无关的(每秒移动固定的比例)。而lerp(current, target, 0.1)这种固定 weight 的写法是帧率相关的——帧率越高移动越快。两种写法在不同场景下都有用,但要注意区别。Vector2、Vector3、Color 也有 Lerp 方法:Godot 中
Vector2.Lerp()、Vector3.Lerp()、Color.Lerp()都是对应类型的线性插值方法,用法类似。Mathf.Lerp()只处理单个浮点数。lerp vs lerpf:在 GDScript 中,
lerp()可以处理 int 和 float 等多种类型,而lerpf()是纯浮点版本。在 C# 中统一使用Mathf.Lerp()。对于角度值的插值,请使用lerp_angle()/Mathf.LerpAngle()来自动处理角度环绕。
