Unity C# Nested IEnumerator

旧街凉风 提交于 2021-02-08 03:35:05

问题


In my code I have nested IEnumerator methods, such like this :

    private IEnumerator PerformRequest(string url) {

        // Doing stuff

        UnityWebRequest request = UnityWebRequest.Get(url);
        yield return request.SendWebRequest();

        // Doing stuff
    }

    private IEnumerator PerformRequest2(string url) {

        // Doing stuff

        return PerformRequest(url);

        // Doing stuff
    }

    public IEnumerator PerformRequest3(string url) {

        // Doing stuff

        return PerformRequest2(url);

        // Doing stuff
    }

I am wondering what is the difference if I add yield in upper level methods, such like this :

    private IEnumerator PerformRequest(string url) {

        // Doing stuff

        UnityWebRequest request = UnityWebRequest.Get(url);
        yield return request.SendWebRequest();

        // Doing stuff
    }

    private IEnumerator PerformRequest2(string url) {

        // Doing stuff

        yield return PerformRequest(url);

        // Doing stuff
    }

    public IEnumerator PerformRequest3(string url) {

        // Doing stuff

        yield return PerformRequest2(url);

        // Doing stuff
    }

Is there a difference, or is it the same behaviour ?

Thank you !


回答1:


Sure, this works

I've done something like this myself before, you can absolutely yield a method that it itself yeilds, because what happens is that execution is completely linear and when PerformRequest yields and returns some value (the web request, but not actually important) that propagates up to the yield return... in PerformRequest2 which then propagates upwards to PerformRequest3. Unity will resume execuction at the correct location just fine (and you could have answered your own question by testing it, too ;).

Basically its the same as any other nested function, e.g

int GetValue() {
    return 4;
}

int GetValue2() {
    return GetValue();
}

Is executed exactly the same as (just with a different type):

IEnumerator GetValue() {
    return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    return GetValue();
}

Which converts to coroutine yielding (yield is just a special keyword, it doesn't effect return type!):

IEnumerator GetValue() {
    yield return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    yield return GetValue();
}

You could also do it like this, but I generally don't find any value in it:

IEnumerator GetValue() {
    yield return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    //other stuff, with yield so our function still returns a value
    StarCoroutine(GetValue());
    //this stuff runs without waiting
}

Adassko also found this great tutorial about coroutines and nested coroutines.




回答2:


It is worth noting in Draco18s answer, that this:

IEnumerator GetValue() {
    // This line won't work.
    yield return new SomeIEnumerator();
}

IEnumerator GetValue2() {
    //other stuff, with yield so our function still returns a value
    StarCoroutine(GetValue());
    //this stuff runs without waiting
}

won't work, cause you need to yield the nested coroutine inside a StartCoroutine call, so it needs to be:

IEnumerator GetValue() {
    // The corrected line.
    yield return StartCoroutine(SomeIEnumerator());
}

IEnumerator GetValue2() {
    //other stuff, with yield so our function still returns a value
    StarCoroutine(GetValue());
    //this stuff runs without waiting
}


来源:https://stackoverflow.com/questions/58436172/unity-c-sharp-nested-ienumerator

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!