如何在 Unity 中插入每次更新都获得新位置的相机?

How to interpolate a camera that gets new position every update in Unity?

我有一个物理赛艇设备,它不断地将赛艇比赛的剩余距离发送给 Unity(即完成比赛还剩 350 米)。当我尝试相应地更新播放器的位置时(仅限 Z 轴),移动不稳定。 我怎样才能插入这种运动以使其更平滑?

我的第一次尝试是这样的:

void Update()
{
   player.position = new Vector3(player.position.x, player.position.y, 
   pm5.Pm5_distance);
}

这导致运动不稳定,可能是因为玩家只是被传送到下一个位置。

接下来我尝试 lerp 到下一个位置,但我不确定我是否做对了,或者这是否有效,因为我的播放器每帧都会收到一个新位置:

private float startTime;
private float journeyLength;
public float speed = 5.0F;

void Start()
{
    startTime = Time.time;
}

void Update()
{
    if (player.position != new Vector3(player.position.x, 
    player.position.y, pm5.Pm5_distance))
    {
        journeyLength = Vector3.Distance(player.position, new 
        Vector3(player.position.x, player.position.y, pm5.Pm5_distance));

        float distCovered = (Time.time - startTime) * speed;

        float fracJourney = distCovered / journeyLength;

        transform.position = Vector3.Lerp(player.position, new 
        Vector3(player.position.x, player.position.y, pm5.Pm5_distance), 
        fracJourney);
    }

}

尽管这不会引发错误,但似乎也无法解决我的问题。也许整个概念是错误的?如果有人能帮助我,我会很高兴。

编辑 25.04.19: 通过尝试使用 David 的代码,我来到了这里:

    void Update()
    {

        if (useLerpMovementModel)
        {
            float newDistance = pm5.Pm5_distance;

            if (player.position.z != newDistance)
            {
                // Distance moved
                float distCovered = journeyLength - pm5.Pm5_distance;

                // Fraction of journey completed = current distance divided by total distance.
                float fracJourney = distCovered / journeyLength;

                // Set our position as a fraction of the distance between the markers.
                transform.position = Vector3.Lerp(player.position, new Vector3(player.position.x, player.position.y, newDistance), fracJourney);
            }
        }
        else
        {
            player.position = new Vector3(player.position.x, player.position.y, journeyLength - pm5.Pm5_distance);
        }

    }

player.position = new Vector3(player.position.x, player.position.y, journeyLength - pm5.Pm5_distance);

相比,我不确定这是否在平滑运动方面有任何作用

下面这行实际上是一个错误的计算:

journeyLength = Vector3.Distance(player.position, new 
        Vector3(player.position.x, player.position.y, pm5.Pm5_distance));

您需要存储旅程开始和结束时的位置,以便您可以在它们之间插入玩家的位置。

我会尝试通过获取您的代码并添加注释来解释必要的内容。我还包括了我推荐的更改以及其他更改:

private float journeyLength;
private Vector3 startPosition;
private Vector3 endPosition;

void Start()
{
    // The total length of the journey, let's imagine it's 100
    // This assumes that when this Start() method is called that
    // pm5.Pm5_distance is equal to the journey length
    journeyLength = pm5.Pm5_distance;
    // Store the player's starting position
    // This will be used to interpolate between start/end
    startPosition = player.position;
    // Store the position that the player will be at when the journey is complete
    // This will be used to interpolate between start/end
    endPosition = startPosition + Vector3.forward * journeyLength;
}

void Update()
{
    // I am assuming that 'pm5.Pm5_distance' is the remaining distance
    if (pm5.Pm5_distance > 0f) 
    {
        // Take the remaining distance from the total journey length to get
        // the current distance travelled. Let's imagine the remaining distance is 50:
        // This will end up being 100 - 50 = 50 units travelled into the journey
        float distCovered = journeyLength - pm5.Pm5_distance;

        // We now get the fraction of the journey that that distance equates to, 
        // which in this case will be 0.5
        float fracJourney = distCovered / journeyLength;

        // Interpolate the players position from where it originally started
        // to the position at the end of the journey (the one we calculated in Start())
        transform.position = Vector3.Lerp(startPosition, endPosition, fracJourney);
    }

}

最后一点,了解 Vector3.Lerp() 函数的工作原理很重要: 它需要两个向量并在它们之间插入一个介于 0 和 1 之间的值。

如果值为 0,则返回第一个向量。

如果值为 1,则返回第二个向量。

如果值为 0.5,则返回介于两者之间的向量。

所以你可以看到在上面的例子中,fracJourney是0.5,这意味着对于这个帧,玩家的位置将恰好在种族。 但在下一帧中,fracJourney 将被重新计算,假设为 0.55。 在该帧中,新位置将比前一帧中的位置稍微向前计算。

这一直持续到最终到比赛终点的距离为 0。