Unity腳本:使用Lerp 線性插值製作滑順效果

Unity腳本:Lerp 線性插值

在Unity中,Lerp一種是用來計算線性插值的函式。

Lerp可以使用在很多個地方,像是:Color.Lerp 、Mathf.Lerp 、Vector3.Lerp 、Material.Lerp 。

Lerp可以用來製作許多滑順的效果。譬如說可以利用Color.Lerp來計算兩個顏色之間的插值,

就可以讓兩種不同的顏色平滑的轉換。

Lerp函式通常長這樣:

.Lerp(from, to, t: float):

其中t代表的是from 與 to之間的差值,是一個介於0~1之間的浮點數。

若t=0則傳回from,,t=1則傳回to,t=0.5則傳回from與to的平均值。

以Vector3.Lerp來說,那from 與 to都會是Vector3型態,傳回值也會是Vector3型態。

我來釐清一下幾個常讓人誤會的地方:

1. 要達成滑順的轉化效果其實是要不斷地呼叫Lerp的。

這原因是因為,Lerp其實僅僅只是計算單一次插值得結果。

並不會自動幫你完成連續的動作。

舉個例子來說,現在有個遊戲物件要從目前的位置移動到位置p1,

那就要在Update中一直呼叫Vector3.Lerp來逼近位置p1。像這樣:

function Update () {
transform.position = Vector3.Lerp(transform.position, p1,  0.1);
}

Lerp函式在transform.position與p1之間計算出十分之一的距離,

然後給傳回ransform.position 以改變現在的位置。

下一次Update時在用新的位置計算與p1十分之一的距離,一直逼近到p1。

2.滑順效果不是線性的。

Lerp是線性插值,但做出的效果不是線性的。

實際上一開始的變化會最快,而越接近目標時變化會越來越慢。

以上面的例子來說,雖然每次都是移動十分之一的距離,

但是其實一開始兩個的位置差距最大,算出來的十分之一當然也最大。

當兩個位置差逐漸縮小時,這十分之一的距離當然也越來越小。

這也意謂這每次Update時,移動的距離越來越小,

最後小到你都看不見。

3.最終值可能不會是to的值。

我猜有人看出來了,這種逼近的值最後可能都不會是真正的to值。

因為我沒有真的做過很多實驗,只就理論來說,所以我只說可能..。

來自官網的簡單js範例

程式碼實現了位置,亮度,與顏色的滑順變化:

程式中的t使用Time.deltaTime,主要是讓不同畫面更新速度的電腦,

單位時間內的變化量是一樣的,不會因為你電腦跑比較快,

所以Update函式執行比較快,結果就導致你的變化量比較快。

#pragma strict

public var smooth : float;

private var newPosition : Vector3;
private var newIntensity : float;
private var newColour : Color;


function Awake ()
{
    newPosition = transform.position;
    newIntensity = light.intensity;
    newColour = light.color;
}


function Update ()
{
    PositionChanging();
    IntensityChanging();
    ColourChanging();
}


function PositionChanging ()
{
    var positionA : Vector3 = new Vector3(-5, 3, 0);
    var positionB : Vector3 = new Vector3(5, 3, 0);
    
    if(Input.GetKeyDown(KeyCode.Q))
        newPosition = positionA;
    if(Input.GetKeyDown(KeyCode.E))
        newPosition = positionB;
    
    transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);
}


function IntensityChanging ()
{
    var intensityA : float = 0.5f;
    var intensityB : float = 5f;
    
    if(Input.GetKeyDown(KeyCode.A))
        newIntensity = intensityA;
    if(Input.GetKeyDown(KeyCode.D))
        newIntensity = intensityB;
    
    light.intensity = Mathf.Lerp(light.intensity, newIntensity, smooth * Time.deltaTime);
}


function ColourChanging ()
{
    var colourA : Color = Color.red;
    var colourB : Color = Color.green;
    
    if(Input.GetKeyDown(KeyCode.Z))
        newColour = colourA;
    if(Input.GetKeyDown(KeyCode.C))
        newColour = colourB;
    
    light.color = Color.Lerp(light.color, newColour, smooth * Time.deltaTime);
}

官網教學:

 
 

  按個讚!~支持本站!~

FB推薦載入中