Почему эта сопрограмма запускается только один раз?

"Что-то" печатается только один раз...

IEnumerator printSomething;

void Start () {

    printSomething = PrintSomething();
    StartCoroutine (printSomething);

}

IEnumerator PrintSomething () {

    print ("Something");

    yield return null;
    StartCoroutine (printSomething);

}

person user3071284    schedule 29.08.2015    source источник


Ответы (3)


Ошибка в вашем подходе заключается в том, что вы сохраняете перечислитель. Перечислитель уже "перечисляет", поэтому передача перечислителя методу StartCoroutine дважды в основном приводит к прямому выходу из сопрограммы, поскольку перечислитель использовался ранее. Запустить сопрограмму снова можно, снова вызвав функцию.

StartCoroutine(PrintSomething());

Но вместо того, чтобы запускать сопрограмму снова и снова, попробуйте вместо этого использовать цикл внутри.

while (true)
{
    print("something");
    yield return null;
}

Это лучше, поскольку внутренняя обработка сопрограммы и ее накладные расходы неизвестны.

person Felix K.    schedule 29.08.2015
comment
На самом деле я обновлю то, что назначено printSomething, что может быть другим IEnumerator. - person user3071284; 29.08.2015

Попробуйте имя сопрограммы вместо указателя. Или сама сопрограмма.

IEnumerator PrintSomething () 
{
    print ("Something");

    yield return null;

    StartCoroutine ("PrintSomething");
}

Or

IEnumerator PrintSomething () 
{
    print ("Something");

    yield return null;

    StartCoroutine (this.PrintSomething());
}
person MahanGM    schedule 29.08.2015

Я столкнулся с точно такой же проблемой, Феликс К. прав в том, что он предполагает, что IEnumerator уже запущен, и сразу же возвращается. Мое решение состояло в том, чтобы передать саму функцию, чтобы мы генерировали новый IEnumerator каждый раз, когда он вызывается. Я надеюсь, что это поможет кому-то еще!

public IEnumerator LoopAction(Func<IEnumerator> stateAction)
{
    while(true)
    {
        yield return stateAction.Invoke();
    }
}

public Coroutine PlayAction(Func<IEnumerator> stateAction, bool loop = false)
{
    Coroutine action;
    if(loop)
    {
        //If want to loop, pass function call
        action = StartCoroutine(LoopAction(stateAction));
    }
    else
    {
        //if want to call normally, get IEnumerator from function
        action = StartCoroutine(stateAction.Invoke());
    }

    return action;
}
person frostymm    schedule 01.01.2020