Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
插值¶
插值是圖形程式設計中一個非常基本的操作. 作為一名圖形開發人員, 熟悉它有助於擴充您的視野.
基本思想是從 A 轉換到 B。t
值是介於兩者之間的狀態。
舉個例子, 如果 t
值為0, 那麼狀態是A. 如果 t
值是1, 狀態是B. 任何介於兩者之間的都是 插值.
在兩個實數(浮點數)之間, 一個簡單的插值通常描述為:
interpolation = A * (1 - t) + B * t
通常簡化為:
interpolation = A + (B - A) * t
這型別的插值名字, 將一個值以 恒定速度 轉換成另一個值 "線性". 當你聽說線性插值時, 就知道他們是指這個簡單的公式.
還有其他型別的插值, 這裡將不做討論. 建議之後閱讀 Bezier 頁面.
向量插值¶
向量型別 (Vector2 和 Vector3) 也可以插值, 它們提供了方便的函式來實作這一點 Vector2.linear_interpolate() 和 Vector3.linear_interpolate().
對於三次插值,還有 Vector2.cubic_interpolate() 和 Vector3.cubic_interpolate() ,它們執行 Bezier 式插值。
下面是使用插值從A點到B點的簡單偽程式碼:
var t = 0.0
func _physics_process(delta):
t += delta * 0.4
$Sprite2D.position = $A.position.lerp($B.position, t)
private float _t = 0.0f;
public override void _PhysicsProcess(double delta)
{
_t += (float)delta * 0.4f;
Marker2D a = GetNode<Marker2D>("A");
Marker2D b = GetNode<Marker2D>("B");
Sprite2D sprite = GetNode<Sprite2D>("Sprite2D");
sprite.Position = a.Position.Lerp(b.Position, _t);
}
它將產生以下運動:
變換插值¶
也可以對整個變換進行插值(確保它們有均勻的縮放,或者至少有相同的非均勻縮放)。對此,可以使用函式 Transform.interpolate_with()。
下面是將猴子從位置1轉換為位置2的例子:
使用以下偽程式碼:
var t = 0.0
func _physics_process(delta):
t += delta
$Monkey.transform = $Position1.transform.interpolate_with($Position2.transform, t)
private float _t = 0.0f;
public override void _PhysicsProcess(double delta)
{
_t += (float)delta;
Marker3D p1 = GetNode<Marker3D>("Position1");
Marker3D p2 = GetNode<Marker3D>("Position2");
CSGMesh3D monkey = GetNode<CSGMesh3D>("Monkey");
monkey.Transform = p1.Transform.InterpolateWith(p2.Transform, _t);
}
又會產生下面的動作:
平滑運動¶
插值可用於平滑運動, 旋轉等. 下面是使用平滑運動跟隨滑鼠的圓圈的例子:
const FOLLOW_SPEED = 4.0
func _physics_process(delta):
var mouse_pos = get_local_mouse_position()
$Sprite2D.position = $Sprite2D.position.lerp(mouse_pos, delta * FOLLOW_SPEED)
private const float FollowSpeed = 4.0f;
public override void _PhysicsProcess(double delta)
{
Vector2 mousePos = GetLocalMousePosition();
Sprite2D sprite = GetNode<Sprite2D>("Sprite2D");
sprite.Position = sprite.Position.Lerp(mousePos, (float)delta * FollowSpeed);
}
如下:
這對平滑相機運動很有用, 隊友在跟隨你(確保他們保持在一定範圍內), 以及許多其他常見的遊戲模式.