我有一个协程,每当玩家到达游戏中的某个点时,我的相机会向上移动。我使用了一个协程,以便相机随着时间的推移顺利移动。
以下是我的代码片段:
private IEnumerator MoveCameraUpCoroutine(Vector3 startPos, Vector3 endPos, float duration)
{
float elapsedTime = 0;
while(elapsedTime < duration)
{
transform.position = Vector3.Lerp(startPos, endPos, (elapsedTime/duration));
elapsedTime += Time.deltaTime;
yield return null;
}
}
public void MoveCameraUp(Vector3 startPos, Vector3 endPos, float duration)
{
StartCoroutine(MoveCameraUpCoroutine(startPos, endPos, duration));
}
在我的控制器脚本中,我只是像这样调用我的协程:
cam.GetComponent<CameraMovement>().MoveCameraUp(cam.transform.position,
new Vector3(cam.transform.position.x, cam.transform.position.y + setupLevel.heightOfBlock, cam.transform.position.z),
0.1f);
这个问题在于相机的运动并不总是一致的。我做了一些调试。在第一次运行时,相机移动到0.7864508 yPos
。在第二次运行时,相机移动到0.7789915 yPos
。等等。
但是,当我只使用Translate
代替我的协程:
cam.transform.Translate(0, setupLevel.heightOfBlock, 0);
我在0.7876318
获得了相机yPos的一致结束值,这正是我所需要的。但是这段代码不会随着时间的推移平稳地移动相机,这不是我想要的。
有谁知道如何修复此协同程序问题?我不知道,但我认为我的协程代码有问题。任何帮助是极大的赞赏。
答案 0 :(得分:1)
结果实际上与预期的结果非常吻合。您的代码完全没有问题,而不是因为帧速率的差异。
您看到细微差别的原因是因为无法保证两个帧会占用准确的渲染时间。 看看这一行
elapsedTime += Time.deltaTime;
您在此处所做的是为您的已用时间添加一个不一致的值。 (即每帧的Time.deltaTime不同)。
一个部分修复可能是使用Time.smoothDeltaTime代替,这是几个帧上deltaTime的平滑值。然而,这并不是完美的。
第二种方法(不完全是答案本身,但我也将此处留给其他人)是使用补间引擎,例如DoTween或iTween。 这些引擎的方法基本上可以满足您的需求。
答案 1 :(得分:0)
float elapsedTime = 0;
float ratio = elapsedTime / duration;
while(ratio < 1f)
{
elapsedTime += Time.deltaTime;
ratio = elapsedTime / duration;
transform.position = Vector3.Lerp(startPos, endPos, ratio);
yield return null;
}
使用此设置,您的循环将一直运行,直到比率为1.当为1时,返回endPos并且循环退出下一轮。
我认为问题在于您将elapsedTime与持续时间进行比较。所以在最后一次运行中,你移动然后你增加并进行比较。结果,不考虑最后一次增加,你最终会在接近结束但不在最后的地方。