CodeGo.net>如何更新Unity GameObject沿样条曲线移动?

下午好,

我正在尝试在Unity中实现一个GameObject,该游戏对象会在给定8个约束随机值的情况下沿着立方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;

谢谢!

马特

解决方法:

您在更新功能中发生2个错误.

第一个错误:

您正在每一帧(segmentNumber)处增加当前段的索引.我猜这应该仅在对象完成它沿着先前的样条线段行进时执行.

暗示:

对于由多个面片定义的样条曲线,我通常将时间(u)表示在[0,n]范围内,其中n是定义曲线的段数.这样,您只需从参数中提取整数部分,即可检索当前补丁的索引(segmentNumber).就像是:

int segmentNumber =  Mathf.FloorToInt(u);
float segmentU = u - segmentNumber;

第二次错误

我不知道您的DT变量是什么,但是除非您通过其他地方的帧增量时间缩放它,否则您必须这样做.基本上,您可以通过以下方式增加时间:

time += Time.deltaTime * speedAlongCurve;

希望对您有所帮助.

上一篇:Unity学习——网络(Networking)


下一篇:最近大火的C4D,为什么游戏影视建模不用它?