Unity腳本:使用Lerp 線性插值製作滑順效果
- 詳細內容
- 分類:Unity
- 發佈:2014-04-16, 週三 23:42
- 點擊數:3514
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); }
官網教學:
按個讚!~支持本站!~