Lerp with Time.deltaTime
我有一个关于 Lerp 的问题。所以我知道 lerp 可以帮助您移动对象,例如:
1 2 3 | void update(){ transform.position = vector3.lerp(start.position,end.position, (Time.time / 1000)); } |
这将使您的对象到达您的终点。
但是如果你有这个代码:
1 2 3 4 5 6 | 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)
变换位置和目标之间的距离呈指数衰减。距离每帧缩小(1 - 速度)(假设速度小于 1)。假设您的游戏应该以 60FPS 运行。如果出于某种原因帧速率下降到 30FPS,则 deltaTime 将增加两倍,并且您应该执行 Lerp 2 次。在这种情况下,距离将收缩 (1 - speed) 然后 (1 - speed) 再次产生 (1 - speed)^2 收缩的结果。由此,您可以概括距离的收缩量为 (1 - speed) ^ (deltaTime / baseDeltaTime),其中 baseDeltaTime 是游戏应该运行的 deltaTime,即 1/60(对于 60FPS)。
输入代码:
1 | transform.position = Vector3.Lerp(transform.position, destination.position, 1 - Mathf.Pow(1 - speed * 3.0f, Time.deltaTime * 60)); |
我猜你不明白 lerp 是如何统一工作的。我会向您推荐 Robbert 的这篇文章如何像专业人士一样 Lerp。
I see this sort of thing far too often:
transform.position = Vector3.Lerp(startPos, endPos, Time.deltaTime); The person posting it is usually convinced that Vector3.Lerp is
a€?brokena€?, but the real problem is that theya€?re not using it correctly.Lerp, short for a€?linear interpolationa€? does one very simple thing:
given two values, x and y, it returns a value that is t percent
between them. If you expect the output to change, the arguments you
pass in need to reflect that!In the example above, it doesna€?t make sense to just pass in
Time.deltaTime, because thata€?s only the time that passed during the
most recent frame. If your game is running at a constant 50fps, thata€?s
always going to be 0.02.
物体到达目标是因为你的起始位置是当前位置,在 lerp 之后,你将物体的位置设置为 Lerp 的结果位置。如果您将起始位置更改为正常的 Vector3,它会 Lerp 到"speed * Time.deltaTime * 3f"
(参见 https://gamedev.stackexchange.com/questions/149103/why-use-time-deltatime-in-lerping-functions)
1。开始和结束之间的线性混合
1 2 | progress = Mathf.Clamp01(progress + speedPerTick); current = Mathf.Lerp(start, end, progress); |
2。朝向目标的指数轻松度
1 | current = Mathf.Lerp(current, target, sharpnessPerTick); |
请注意,在此版本中,
这个参数不再是一个"速度",因为我们以类似 Zeno 的方式接近目标。如果
这给出了一个"指数缓动",当远离目标时运动很快,随着渐近接近而逐渐减慢(尽管对于无限精度数,它永远不会在任何有限次数的更新中达到它 - 因为我们的目的它已经足够接近了)。它非常适合追踪移动目标值,或使用"指数移动平均线"平滑噪声输入,通常使用非常小的
1 | myLocation = Mathf.Lerp(myLocation, myDestination, 0.02) |
如果您将
所以,即使你没有改变 T,你也在改变起始值,因此,存储的值越来越接近最大值。
它最初会非常快地加速,然后随着接近最大值而减速。此外,最大值永远不会达到或需要很长时间。