Защо тази Coroutine се изпълнява само веднъж?

"Нещо" се отпечатва само веднъж...

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