循序渐进启动协程

时间:2018-11-04 09:08:59

标签: c# unity3d coroutine ienumerator

我有一个包含GameObjects的列表(称为路径)。当前的GameObject(带有脚本)应从GameObjects在路径中的一个位置逐步移动到下一个位置。我当前的代码使它立即移动到路径的最后一个位置。我已经在协程结束时尝试过WaitForSeconds,但是由于它们都是一次启动的,所以没有效果。

我该怎么做才能获得循序渐进的效果?

到目前为止,这里是我的代码:

public List<GameObject> path;
private Vector3 start;
private Vector3 target;
private float lungeSpeed = .8f;
private float lungeDistance = 5;
private IEnumerator coroutine;

public void StartPath() {
        foreach (GameObject field in path) {
            start = transform.position;
            target = new Vector3(field.transform.position.x + lungeDistance, field.transform.position.y, field.transform.position.z);
            coroutine = MoveObject(start, target, lungeSpeed);
            StartCoroutine(coroutine);
        }
    }

IEnumerator MoveObject(Vector3 start, Vector3 target, float speed)
    {
        float t = 0.0f;
        float rate = 1.0f / speed;
        while (t < 1.0)
        {
            t += Time.deltaTime * rate;
            transform.position = Vector3.Lerp(start, target, t);
            yield return null;
        }
        yield return new WaitForSeconds(1);
    }

1 个答案:

答案 0 :(得分:3)

目前,您在StartPath中的代码没有等待MoveObject完成。您可以通过在协程中运行StartPath并使用yield return MoveObject(start, target, lungespeed)来解决此问题。

startPath完成MoveObject之前,Still仍将停止执行yield return new WaitForSeconds中的foreach循环

public IEnumerator StartPath() {
    foreach (GameObject field in path) {
        start = transform.position;
        target = new Vector3(field.transform.position.x + lungeDistance, field.transform.position.y, field.transform.position.z);
        coroutine = MoveObject(start, target, lungeSpeed);
        yield return StartCoroutine(coroutine);//this will keep the foreach loop from iterating untill the coroutine has finished
    }
}

还有一点注意事项:

  

(因为协程是在新的并行线程中执行的)

不正确。协程不会在单独的线程上运行。协程与其余所有代码一样在主线程上运行,它只是在根据自己的yield语句(但仍在主线程上)暂停和恢复执行的地方做了一点小技巧。

如果要在单独的线程上运行某些程序,则需要调用new Thread()。但是,这是一块不同的蛋糕,因为线程无法从Monobehaviour继承