@ananas_roma
Пытаюсь кодить.

Почему данный код не работает?

Здравствуйте!

Имеется такой кусок кода:
void ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i=0; i<pointss.Count; i++)
        {
            StartCoroutine(ExecuteAfterTime());
            temp.transform.position = pointss[i];
        }
    }

    IEnumerator ExecuteAfterTime()
    {
        yield return new WaitForSeconds(1);
    }


Смысл в том, что я GameObject таскаю по какой-то траектории. Переход между координатами - 1 секунда. Но на проверке объект сразу находится в конце, а не "проходит" по пути. В чем проблема?
  • Вопрос задан
  • 648 просмотров
Решения вопроса 1
MrMureno
@MrMureno Куратор тега Unity
VR for all
попробую пояснить как то попроще что ли))

Вот вы запустили короутину в строке
StartCoroutine(ExecuteAfterTime());
оно тут же начнет её выполнять, и выполнит все вызовы внутри короутины пока не наткнется на какое нибудь "подождать", в вашем случае
yield return new WaitForSeconds(1);

наткнулось -> вернулось тут же в основной поток и продолжило выполнять
temp.transform.position = pointss[i]; и далее цикл.

и условно спустя "подождать", оно продолжит выполнять короутину (снова из основного потока заглянув в нее)
(на деле там конечно малость иначе, но для понимания сойдет)

void ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i=0; i<pointss.Count; i++)
        {
            StartCoroutine(ExecuteAfterTime());
           Debug.Log("from FOR _"+i.ToString());
            temp.transform.position = pointss[i];
        }
    }

    IEnumerator ExecuteAfterTime()
    {
        yield return new WaitForSeconds(1);
       Debug.Log("Arter 1 second");
    }


попробуйте вот такой код и поймете, когда и что вызывается.
и что в общем то верно вам пояснили, что если хотите растянуть цикл во времени, то весь его в короутину запихать.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
GavriKos
@GavriKos Куратор тега Unity
Потому что ваш код неправильный. Надо все засовывать в корутину.
Ответ написан
Комментировать
@CHolfield
Потому что в доках писано:

A StartCoroutine function terminates immediately, however, the Coroutine it creates runs as expected.

То есть, нихрена этот вызов не синхронный, ожидающий секунду оператор оказывается в другом потоке, а вызывающий продолжается без всяких пауз.

А чтоб как тебе надо было пиши так:

yield return StartCoroutine(.... и т.д.
Или вместо вызова корутины пиши
yield return new WaitForSeconds(1);
Ответ написан
Комментировать
@VoLandMonk
Вот так все будет работать:
void ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i=0; i<pointss.Count; i++)
        {
            StartCoroutine(ExecuteAfterTime(1, i));
            
        }
    }

    IEnumerator ExecuteAfterTime(int second, int incr)
    {
        yield return new WaitForSeconds(second);
        temp.transform.position = pointss[incr];
    }
Ответ написан
Комментировать
Exomode
@Exomode
Архитектор ПО
Да цикл в корутину засуньте и один раз ее вызовите, зачем такие конструкции городите?
А вообще, в последних версиях уже давно можно делать вот так:
async Task ChangePos(List<Vector2> pointss, GameObject temp)
    {
        for (int i = 0; i < pointss.Count; i++)
        {
            temp.transform.position = pointss[incr];
            await Task.Delay(1000);
        }
    }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы