1

我有一个关于 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,以便您的对象到达您的目的地。但是 "speed" , "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)

4

5 回答 5

2

你的变换位置和目的地之间的距离是指数衰减的。距离每帧缩小(1 - 速度)(假设速度小于 1)。假设您的游戏应该以 60FPS 运行。如果出于某种原因帧速率下降到 30FPS,则 deltaTime 将是原来的两倍,并且您应该执行 Lerp 2 次。在这种情况下,距离将收缩 (1 - speed) 然后 (1 - speed) 再次产生 (1 - speed)^2 收缩的结果。由此,您可以概括距离的收缩量是 (1 - speed) ^ (deltaTime / baseDeltaTime),baseDeltaTime 是游戏应该运行的 deltaTime,即 1/60(对于 60FPS)。输入代码:

transform.position = Vector3.Lerp(transform.position, destination.position, 1 - Mathf.Pow(1 - speed * 3.0f, Time.deltaTime * 60));
于 2019-06-12T16:47:39.163 回答
1

我猜你不明白 lerp 是如何统一工作的。我会像专业人士一样向您推荐 Robbert How to Lerp 的这篇文章。

我经常看到这种事情:

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

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

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

在上面的示例中,只传递 Time.deltaTime 是没有意义的,因为那只是在最近一帧中经过的时间。如果您的游戏以恒定的 50fps 运行,则始终为 0.02。

于 2017-05-02T11:46:56.387 回答
1

对象到达目标是因为您的起始位置是当前位置,并且在 lerp 之后,您将对象的位置设置为 Lerp 的结果位置。如果您将起始位置更改为正常的 Vector3,它将 Lerp 变为“speed * Time.deltaTime * 3f”

于 2017-05-01T14:56:37.893 回答
0
myLocation = Mathf.Lerp(myLocation, myDestination, 0.02)

如果您将Lerp函数的返回值存储到一个变量中,然后还使用该变量作为同一Lerp函数中的最小值,那么每次调用该函数时,最小值都会变得越来越大。

所以,即使你没有改变 T,你也在改变起始值,因此,存储的值越来越接近最大值。

它最初会非常快地加速,然后在接近最大值时减速。此外,最大值将永远不会达到或需要很长时间。

于 2019-09-25T22:51:57.963 回答
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记忆从一帧到下一帧的原因。然后,从这个移动的起点出发,我们将一小部分距离移向targetsharpness参数指定的距离。

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

这给出了一个“指数缓动”,当远离目标时运动很快,随着渐近接近而逐渐减慢(尽管对于无限精度的数字,它永远不会在任何有限数量的更新中达到它 - 出于我们的目的足够接近)。它非常适合追踪移动目标值,或者使用“指数移动平均线”平滑噪声输入,通常使用非常小的sharpnessPerTick参数,例如0.1或更小。

于 2020-02-10T07:21:56.667 回答