Lerp 实现匀速运动「建议收藏」
Lerp函數在Mathf,Vector3, 等類中都有,用法都類似,作用都是按照百分比取得從一個值過度到另外一個值的中間值。下面說的內容針對各中類的Lerp函數都是通用的。
Lerp的常見“誤用”是
Update()
{
Transform.position = Vector3.Lerp(transform.position.x, targetPosition, Time.deltaTime);
}
Jetbrains全家桶1年46,售后保障穩定
說是“誤用”,其實也不完全正確,這種用法是可以工作的,但是常常不是大家的真正需求,很多時候大家使用Lerp都是想達到勻速運動的效果,但如下“誤用”卻讓對象以逐漸降低的速度運動。
首先,上述“誤用”是這樣工作的:每幀都重新獲取物體當前的位置,計算物體和目標距離的差距,再按照當前幀的持續時間(當做一個百分比)來移動這個比例的位置。因此如果目標位置始終是固定的,那么整體運動是緩動的,先快后慢。這樣的效果乍一看還不錯,但其實是有一些問題的:因為每秒鐘都以固定的比例靠近目標位置,所以運動速度會以固定的比例逐漸降低,只要運算精度夠高,運動永遠達不到目標,且運算始終在進行。如果確實需要這樣做,那么我們需要加上一個閾值,當與目標距離小于這個閾值時,就直接把物體的位置設置為目標位置。這個閾值的大小設置要合適,太大了在后面階段會感覺到明顯的跳躍,太小了會浪費運算時間。
這里說明一下,如果上述效果就是我們想達到的目標,那么用Time.deltaTime作為第三個參數在這個情況下是有道理的,因為每幀時間不同,為了保證單位時間內運動的百分比是一致的(達到平滑緩動的效果),需要用Time.deltTime介入。
如果你是誤打誤撞實現了緩動效果,并且覺得效果不錯就沒有再深究了,那么建議你繼續往下看看。
用Lerp來實現勻速運動的代碼
先看代碼:
float speed = 2.0f;
//什么時候開始運動
float startTime = 2.0f;
//起始X位置
float startX = 0.0f;
//結束X位置
float endX = 0.0f;
void Update()
{
float lerpValue = Mathf.Lerp(startX,endX,(Time.time-startTime )* speed);
transform.position = new Vector3(lerpValue,0,0);
}
一定要理解清楚Mathf.Lerp(float a, float b, float t)第三個參數t的意義,它是一個百分比,最小值有效值是0,最大有效值是1,如果超出了1,就取1,小于0則取0.
它表示從a到b之間,按照t這個百分比來取值,例如a是0,b是100,如果t是0.2,則該函數返回的值是20,如果t是1,該函數返回的值為100.
勻速運動的要點是起始值和結束值都是固定好的,不會隨著運動而發生變化。
Time.time就是系統運行時間,也就是這個程序開始到現在的時長。
(Time.time – startTime),上面例子中startTime是2.0f,那么這個式子的取值一開始是-2,2秒時變成0,3秒時變成1,先假設沒有乘以speed這個值,整個運動過程會在2秒開始,3秒結束。
物體運動的速度是距離差(在本例中是10.0f)除以1秒。乘以一個speed以后,實際上是在調整整體的運動時間。
假設speed為0.1f,則運動的時間變為2秒開始12秒結束,運行時間變成了10,則速度變成原先的1/10,
同理,假設speed 為10f,則運動時間變為2秒開始2.1秒結束,速度變成原先的10倍。
總結
以上是生活随笔為你收集整理的Lerp 实现匀速运动「建议收藏」的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RxJs fromEvent 工作原理分
- 下一篇: RxJs map operator 工作