Lerp with Time.deltaTime

时间:2017-05-01 14:22:37

标签: unity3d time lerp

我有一个关于Lerp的问题。所以我知道lerp可以帮助你移动你的对象,如:

void update(){
transform.position = vector3.lerp(start.position,end.position, (Time.time / 1000));
}

这将使你的对象达到你的目的地。 但是如果你有这个代码:

void Update(){

    transform.position = Vector3.Lerp(transform.position,
                                      destination.position,
                                      speed * 3.0f * Time.deltaTime);
}

你的物体到达目的地的可能性如何,lerp的第3个参数必须慢慢达到1,这样你的物体就会到达你的目的地。但是"速度" ," 3.0" ," Time.deltaTime"将永远是相同的,那么你的对象如何到达你的目的地呢?

所以最大的问题是:是否可以使用一些变量来执行lerp,这些变量总是具有相同的值和Time.deltaTime?

现在,由于评论不同等等,我不确切知道lerp是如何工作的,我有可能:

1。)首先我认为它的工作原理如下:

Vector3.lerp(A,B,C) c值必须每帧都改变以移动对象。如果c值为0.2,则对象将移动20%,如果c值未更改,则对象将始终处于20%的路径上。因此,让对象移动得很流畅,你的c值必须稍微改变每一帧,所以你的c值将从0变为1,你的对象从开始到目的地也是如此。

或者就像这样

2。)由于有几条评论,我认为lerp就像这样

就像评论所说的那样,c值不必改变数值,因为如果你有c = 0.2,你将通过20%的路和下一帧,如果c仍为0.2,你将通过剩余方式的20%等等。

所以lerp像1一样工作(你必须改变c)或者它是否像2那样工作(你不必改变c)

5 个答案:

答案 0 :(得分:0)

对象到达目标,因为您的起始位置是当前位置,并且在搜索之后,您将对象的位置设置为Lerp的结果位置。如果你将你的起始位置改为普通的Vector3,那么Lerp会“加速* Time.deltaTime * 3f”

答案 1 :(得分:0)

我猜你不明白lerp如何在统一中发挥作用。我会向您推荐Robbert How to Lerp like a pro的这篇文章。

  

我经常看到这种事情:

     

transform.position = Vector3.Lerp(startPos, endPos, Time.deltaTime);

     

发布它的人通常确信Vector3.Lerp是   “破碎”,但真正的问题是他们没有正确使用它。

     

Lerp,“线性插值”的缩写是一个非常简单的事情:   给定两个值x和y,它返回一个t%的值   它们之间。如果您希望输出发生变化,那么您就可以参与其中   传递需要反映!

     

在上面的例子中,传入是没有意义的   Time.deltaTime,因为那只是时间过去了   最近的帧。如果你的游戏以50fps的速度运行,那就是   总是0.02。

答案 2 :(得分:0)

您的变换位置和目标之间的距离是指数衰减。距离每帧缩小(1-速度)(假设速度小于1)。假设您的游戏运行速度为60FPS。如果由于某种原因帧速率降至30FPS,则deltaTime会大一倍,并且您应该执行两次Lerp。在这种情况下,距离将缩小(1-速度),然后缩小(1-速度),从而产生(1-速度)^ 2缩小的结果。由此可以得出结论,距离的缩小量为(1-速度)^(deltaTime / baseDeltaTime),其中baseDeltaTime是游戏应该以1/60(对于60FPS)运行的deltaTime。 要输入代码:

transform.position = Vector3.Lerp(transform.position, destination.position, 1 - Mathf.Pow(1 - speed * 3.0f, Time.deltaTime * 60));

答案 3 :(得分:0)

myLocation = Mathf.Lerp(myLocation, myDestination, 0.02)

如果将Lerp函数的返回值存储到一个变量中,然后又在同一Lerp函数中使用与最小值相同的变量,那么最小值将越来越大每次调用该函数。

因此,即使您没有更改T,也正在更改起始值,因此,存储的值越来越接近最大值。

开始时它将非常迅速地加速,然后在接近最大值时减速。而且,将永远无法达到最大值,或者花费极长时间。

答案 4 :(得分:0)

(请参见https://gamedev.stackexchange.com/questions/149103/why-use-time-deltatime-in-lerping-functions

有两种常用的Lerp使用方式:

1。起点和终点之间的线性融合

progress = Mathf.Clamp01(progress + speedPerTick);
current = Mathf.Lerp(start, end, progress);

2。达到目标的指数轻松程度

current = Mathf.Lerp(current, target, sharpnessPerTick);

请注意,在此版本中,current值同时显示为输出。它替换了start变量,因此我们总是从上次更新的位置开始。这就是Lerp这个版本从一帧到下一帧的存储空间。然后,从这个移动的起点开始,将target参数所指示的距离的一部分移向sharpness

此参数不再是“速度”,因为我们以Zeno-like的方式接近目标。如果sharpnessPerTick0.5,则在第一次更新时,我们将移到目标的一半。然后,在下一次更新中,我们将移动剩余距离的一半(因此是初始距离的四分之一)。然后在下一个我们再移动一半...

这提供了“指数缓和”,当远离目标时,运动很快,随着渐近而逐渐减慢(尽管具有无限精度数字,它在任何有限数量的更新中都不会达到它)我们的目的就足够接近了)。通常,它使用非常小的sharpnessPerTick参数(例如0.1或更小)来跟踪移动的目标值或使用“ exponential moving average”来平滑嘈杂的输入,非常有用。