線性插值(Lerp)

Mathf.Lerp 是 Unity 中的一個數學函數,用於在兩個值之間進行線性插值(Linear Interpolation)。
這個函數可以幫助你製作平滑的效果,像是顏色轉換,動畫轉換等。

語法為 float Mathf.Lerp(float a, float b, float t)

  • a :起始值
  • b :結束值
  • t :代表 ab 之間的插值比例,範圍在 0 到 1 之間。如果 t 為 0,則返回 a;如果 t 為 1,則返回 b;如果 t 為 0.5,則返回 a 和 b 之間的中間值(0.5)。
  • 例如: Mathf.Lerp (3f, 5f, 0.5f) 會得到 4 。

我們來看一個例子,假設 a=0 , b=20 , t=0.5 。 每一秒執行一次,並將結果儲存回 a

  • 開始: a=0 ,
  • 第一秒: a = Mathf.Lerp (0f, 20f, 0.5f) = 10
  • 第二秒: a = Mathf.Lerp (10f, 20f, 0.5f) = 15
  • 第三秒: a = Mathf.Lerp (15f, 20f, 0.5f) = 17.5

將結果畫為一個座標圖,其中 X 軸代表時間(每一秒), Y 軸代表每一秒執行之後的 a

a: b: t: time:

可得出以下簡單的結論

  • 隨著時間增加 a 會從開始快速增加,但是當越接近 b 時,成長的速度就會越慢。

下面是一個使用 Mathf.Lerp 調整光強度的例子。

  • 假設光的強度從 0 開始
  • 在第一次更新幀後: Mathf.Lerp(0f, 8f, 0.5f) 得到的值為 4
  • 第二次更新幀後: Mathf.Lerp(4f, 8f, 0.5f) 得到的值為 6
  • 第三次更新幀後: Mathf.Lerp(6f, 8f, 0.5f) 得到的值為 7
  • 第四次更新幀後: Mathf.Lerp(7f, 8f, 0.5f) 得到的值為 7.5
  • …依此類推,最後將趨近於 8 ,但是隨著 a 的值接近 b ,其變化的速率將減慢。
    1
    2
    3
    4
    5
    6
    7
    8
    void Start() 
    {
    light.intensity = 0;
    }
    void Update ()
    {
    light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f);
    }

下面的程式碼將展示如何使用 Mathf.Lerp 來在兩個值之間做插值,讓一個遊戲物件來回移動。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Example : MonoBehaviour
{
// 定義遊戲物件在X軸上的移動範圍
public float minimum = -1.0F; // 最小值 -1.0
public float maximum = 1.0F; // 最大值 1.0


// Lerp 的初始值
static float t = 0.0f;

void Update()
{
// 使用 Lerp 函數在 minimum 和 maximum 之間插值,這個遊戲物件一開始將從 minimum 移動到 maximim
transform.position = new Vector3(Mathf.Lerp(minimum, maximum, t), 0, 0);

// 增加 t 的值,0.5f * Time.deltaTime 來控制插值的速度
t += 0.5f * Time.deltaTime;

// 當 t 超過 1.0 時,將 t 重置為 0 並交換 minimum 和 maximum
// 這樣物件將開始從 maximum 移動回 minimum
if (t > 1.0f)
{
float temp = maximum;
maximum = minimum;
minimum = temp;
t = 0.0f;
}
}
}

使用 0.5f * Time.deltaTime 的原因是:確保增量操作(例如移動或旋轉)在不同的幀率下保持一致。這樣,無論遊戲以每秒 30 幀還是每秒 60 幀運行,物件的移動速度都會保持一致。
舉個例子:假設你的遊戲每秒運行 60 幀,則 Update 每一秒會執行 60 次, 那麼每幀的 Time.deltaTime 約為 1/60 秒 ≈ 0.0167 秒

  • 如果想要讓每秒 t 增長的量為 0.5f , 以每一幀來看, t 增長的量要為 0.5f * 0.0167 ≈ 0.0083 , 這樣在執行 60 次 Update 後約為一秒 => 0.5f * 0.0167 * 60 ≈ 0.5f

另外還有 Color.LerpVector3.Lerp 這些方法的工作方式與 Mathf.Lerp 完全相同,差別在於輸入 ab 的類型

Reference:

評論