Unity - need to return value only after coroutine finishes

ⅰ亾dé卋堺 提交于 2019-11-26 14:46:49

Only a coroutine can wait for another coroutine. Since you need to wait for the coroutine you started (WaitForRequest), it means you have to convert POST to be a coroutine and it won't be able to return int.

It looks like success_fail is a member variable, so if that's exposed to whoever is starts POST (as a coroutine), you wouldn't need to return it anyway.

public int success_fail

IEnumerator POST(string username, string passw)
{
    WWWForm form = new WWWForm();
    form.AddField("usr", username);
    form.AddField("pass", passw);

    WWW www = new WWW(url, form);

    yield return StartCoroutine(WaitForRequest(www));
}

private IEnumerator WaitForRequest(WWW www)
{
    yield return www;
    if (www.error == null)
    {
        if(www.text.Contains("user exists"))
            {
                success_fail = 2;
            }
            else
            {
                success_fail=1;
            }
    } else {
        success_fail=0;
    }    
}

Basically, if you want your code to "wait", it has to be a coroutine. You can't make a call that waits without blocking the whole engine (without some type of loop hack).

This thread gives a way where you could return the int from your coroutine if you really need to, but POST still can't be a blocking call...

http://answers.unity3d.com/questions/24640/how-do-i-return-a-value-from-a-coroutine.html

Grimmdev

Functions don't wait for coroutines before return, however you could use an Action to give some kind of return.

Put this in your Start function

WWW www = new WWW("http://google.com");

StartCoroutine(WaitForRequest(www,(status)=>{
    print(status.ToString());
}));

and add this.

private IEnumerator WaitForRequest(WWW www,Action<int> callback) {
    int tempInt = 0;
    yield return www;
    if (string.IsNullOrEmpty(www.error)) {
        if(!string.IsNullOrEmpty(www.text)) {
            tempInt = 3;
        }
        else {
            tempInt=2;
        }
    } else {
        print(www.error);
        tempInt=1;
    }
    callback(tempInt);
}

Give this a try, although the function can change a value it doesn't return a value and only has a single parameter. So in essence this isn't a solution for returning your coroutine however once received the int from the coroutine we are then able to justify what to do with it and even call other functions from within the callback.

StartCoroutine(WaitForRequest(www,(status)=>{
    print(status.ToString());
    Awake(); // we can call other functions within the callback to use other codeblocks and logic.
    if(status != 0)
        print("yay!");
    }
));

This might be of use to you. http://answers.unity3d.com/questions/744888/returning-an-ienumerator-as-an-int.html

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