我有一个矢量点列表,它定义了一个对象所遵循的直线段的路径。目前,我进行线性插值以沿着路径动画运动,如下所示:
public class Demo
{
public float speed = 1;
private List<Vector3> points;
private float t; // [0..1]
private Vector3 Evaluate(float t)
{
// Find out in between which points we currently are
int lastPointIndex = GetLast(t);
int nextPointIndex = GetNext(t);
// Obviously, I need to somehow transform parameter t
// to adjust for the individual length of each segment.
float segmentLength = GetLength(lastPointIndex, nextPointIndex);
// But how would I do this?
return Vector3.Lerp(points[lastPointIndex], points[nextPointIndex], t);
}
public void Update()
{
// Curve parameter t moves between 0 and 1 at constant speed.
t = Mathf.PingPong(Time.time * speed, 1);
// Then just get the evaluated position for the curve time, but
// this gives variant speed if points are not evenly spaced.
Vector3 position = Evaluate(t);
SetObjectPosition(position);
}
}
我意识到,要实现恒定速度,我需要重新调整参数t以考虑每个段的长度,但我似乎无法确切知道如何。
我也知道,我可以通过以我想要的速度向下一个点移动来近似路径,只改变方向,一旦我靠近或跟踪t并且一旦它移动到方向上就改变方向下一段,但这看起来很糟糕,当我实际知道每个段的确切长度时,应该能够完全插入它。
答案 0 :(得分:0)
这实际上很安静。首先,为对象定义所需的速度。例如,每秒6个单位。这意味着如果一个线段的长度为6个单位,那么你的对象需要1秒才能从它的开始到结束点。这也意味着如果你的线段长度是这个长度的一半(即3个单位),它将需要0.5秒的物体穿过它。因此,您需要做的是计算所有线段的长度,并将其除以您想要的速度(3/6 = 0.5 = scaleFactor)
。然后,不是在0和1之间进行插值,而是在0和1*scaleFactor
之间进行插值。然后你的代码变成:
public class Demo
{
public float speed = 1;
private List<Vector3> points;
private float t; // [0..1]
private Vector3 Evaluate(float t)
{
// Find out in between which points we currently are
int lastPointIndex = GetLast(t);
int nextPointIndex = GetNext(t);
float segmentLength = GetLength(lastPointIndex, nextPointIndex);
float scaleFactor = segmentLength/speed;
// note that I divided t by scaleFactor instead of multiplication.
// That's because Lerp always takes an interval of [0..1]. So, we
// adjust the curve parameter instead.
return Vector3.Lerp(points[lastPointIndex], points[nextPointIndex], t/scaleFactor);
}
public void Update()
{
// Curve parameter t moves between 0 and 1 at constant speed.
t = Mathf.PingPong(Time.time * speed, 1);
// Then just get the evaluated position for the curve time, but
// this gives variant speed if points are not evenly spaced.
Vector3 position = Evaluate(t);
SetObjectPosition(position);
}
}