我想写一个IEnumerator,让它在指定的时间内按想要的距离移动。我曾试着写过这样的代码,但运行方式不同。
float moveDistance=1f;
float moveSpeed=5f;
float elapsedDistance = 0f;
while (elapsedDistance <= moveDistance)
{
elapsedDistance += Time.deltaTime * moveSpeed;
Vector3 cubeLocalPosition = transform.localPosition;
cubeLocalPosition.y += Time.deltaTime * moveDistance;
transform.localPosition = cubeLocalPosition;
yield return null;
}
通过这段代码,Object无法移动1个单位的距离。我怎样才能纠正这段代码?
你的 while 循环条件使用的是 elapsedDistance,而 elapsedDistance 是随着 moveSpeed 的增加而增加的。后者是5,所以它将是1/15秒。你的对象可能只移动了0.2个单位。
你应该使用Mathf.Lerp或MoveTowards。
float distance = 1f;
float time = 0f;
float period = 1f; // how long in second to do the whole movement
yield return new WaitUntil(()=>
{
time += Time.deltaTime / period;
float movement = Mathf.Lerp(0f, distance, time);
Vector3 cubeLocalPosition = transform.localPosition;
cubeLocalPosition.y += movement;
transform.localPosition = cubeLocalPosition;
return time >= 1f;
});
按照自己的旋转,计算出最后的点,然后再去,你可以使用 Vector3.Lerp 或 Vector.Slerp 因此,移动速度会根据所需时间自行调整。
var endpoint = transform.position + transform.forward.normalized * distance;
StartCoroutine(MoveToPosition(transform, endpoint, 3f)
:
:
public IEnumerator MoveToPosition(Transform transform, Vector3 positionToGO, float timeToMove)
{
var currentPos = transform.position;
var t = 0f;
while (t < 1f)
{
t += Time.deltaTime / timeToMove;
transform.position = Vector3.Lerp(currentPos, positionToGO, t);
yield return null;
}
transform.position = positionToGO;
}
你需要改变IEnumerator的返回值,以便让coroutine等待从上一帧开始的时间。你可以使用 等待时间 来做到这一点。
yield return new WaitForSeconds(Time.deltaTime);
这样一来,你就会 "模仿 "鱼子酱的。更新 回调(更新 时间.deltaTime).