下午好,
我试图在Unity中实现一个游戏对象,该游戏对象在给定8个约束随机值的情况下沿着Cubic CatMull-Rom样条曲线移动。我已经实现了一个函数 ComputePointOnCatmullRomCurve ,它返回一个立方Catmull-Rom曲线上的一个点(给定一个标量' u'从0到1和segment_number表示哪个4点到用于插值)。
我无法实现更新功能以允许GameObject顺利移动。我目前正在调用 ComputePointOnCatmullRomCurve 每次更新,并且每次都会增加segment_number。然后将GameObjects位置设置为函数的结果。
然而,这导致GameObject移动得非常快。我相信我的Update函数是不正确的,但我不确定如何相对于插值函数输出的点移动GameObject。
如果有人能够向我解释我做错了什么,或提供示例或链接到示例,那将非常有用!
计算曲线上点的函数:
Vector3 ComputePointOnCatmullRomCurve(float u, int segmentNumber)
{
// TODO - compute and return a point as a Vector3
// Points on segment number 0 start at controlPoints[0] and end at controlPoints[1]
// Points on segment number 1 start at controlPoints[1] and end at controlPoints[2]
// etc...
Vector3 point = new Vector3();
float c0 = ((-u + 2f) * u - 1f) * u * 0.5f;
float c1 = (((3f * u - 5f) * u) * u + 2f) * 0.5f;
float c2 = ((-3f * u + 4f) * u + 1f) * u * 0.5f;
float c3 = ((u - 1f) * u * u) * 0.5f;
Vector3 p0 = controlPoints[(segmentNumber - 1) % NumberOfPoints];
Vector3 p1 = controlPoints[segmentNumber % NumberOfPoints];
Vector3 p2 = controlPoints[(segmentNumber + 1) % NumberOfPoints];
Vector3 p3 = controlPoints[(segmentNumber + 2) % NumberOfPoints];
point.x = (p0.x * c0) + (p1.x * c1) + (p2.x * c2) + (p3.x * c3);
point.y = (p0.y * c0) + (p1.y * c1) + (p2.y * c2) + (p3.y * c3);
point.x = (p0.z * c0) + (p1.z * c1) + (p2.z * c2) + (p3.z * c3);
return point;
}
更新功能
void Update () {
// TODO - use time to determine values for u and segment_number in this function call
// 0.5 Can be used as u
time += DT;
segCounter++;
Vector3 temp = ComputePointOnCatmullRomCurve(time, segCounter);
transform.position = temp;
}
变量:
const int NumberOfPoints = 8;
Vector3[] controlPoints;
const int MinX = -5;
const int MinY = -5;
const int MinZ = 0;
const int MaxX = 5;
const int MaxY = 5;
const int MaxZ = 5;
float time = 0;
const float DT = 0.01f;
public static int segCounter = 0;
谢谢!
马特
答案 0 :(得分:4)
您在更新功能中遇到2个错误。
第一个错误:
您正在递增每帧(segmentNumber
)处当前片段的索引。我想这应该只在对象完成它沿着前一个样条线段移动时才能完成。
提示:
对于由多个补丁定义的样条曲线,我通常表示u
范围内的时间([0,n]
),其中n
是定义曲线的段数。这样,您可以检索当前补丁(segmentNumber
)的索引,只需从参数中提取整数部分。类似的东西:
int segmentNumber = Mathf.FloorToInt(u);
float segmentU = u - segmentNumber;
第二次错误
我不知道您的DT变量是什么,但除非您按照其他地方的帧增量时间进行缩放,否则您必须这样做。基本上你可以这样增加时间:
time += Time.deltaTime * speedAlongCurve;
我希望它有所帮助。