Запускайте Coroutine шаг за шагом в цикле

У меня есть список (называемый путем) с 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);
    }

person maidi    schedule 04.11.2018    source источник


Ответы (1)


Прямо сейчас ваш код в StartPath не ожидает завершения MoveObject. Вы можете решить эту проблему, запустив StartPath в сопрограмме и используя yield return MoveObject(start, target, lungespeed).

Все еще остановит выполнение цикла foreach в startPath до тех пор, пока MoveObject не завершится с yield return new WaitForSeconds

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(). Однако это совершенно другой кусок пирога, поскольку поток не может наследовать от моноповедения.

person Remy    schedule 04.11.2018
comment
Спасибо за ваше замечание, я изменил свой вопрос, чтобы удалить неверную информацию. - person maidi; 05.01.2019