Unity - you need to return a value only after coroutine completes

I am working on a game in unity and have encountered a problem that I cannot solve. I connect to the web server through a standard WWW object and using coroutine to execute the POST request.

The code itself works, but I need to update the value of the variable and return this variable after coroutine has finished, which I cannot do.

public int POST(string username, string passw) { WWWForm form = new WWWForm(); form.AddField("usr", username); form.AddField("pass", passw); WWW www = new WWW(url, form); StartCoroutine(WaitForRequest(www)); //problem is here ! return success_fail; } 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; } } 

The coroutine program updates the value "success_fail" with the corresponding value. But "return success_fail"; a line in the POST method is executed before coroutine completes, which returns a false value.

I tried to use an additional coroutine, but to no avail, suppose I also had an error. How can I return the value of "success_fail" only after coroutine completes?

Thanks.

+5
source share
2 answers

Only a coroutine can wait for another coroutine. Since you need to wait when you send the coroutine (WaitForRequest), this means that you need to convert the POST to the coroutine, and it will not be able to return an int.

Success_fail seems to be a member variable, so if someone runs POST (as a coroutine), you still won't need to return it.

 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 should be a coroutine. You cannot make a call that is waiting without blocking the entire engine (without any hacking of the loop).

In this thread, you can return int from your coroutine if you really need to, but POST still cannot be a blocking call ...

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

+2
source

Functions do not wait for coroutines before returning, however you can use 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); } 

Try this attempt, although the function can change a value that does not return a value and has only one parameter. Thus, in fact, this is not a solution for returning your coroutine, however, after receiving the int from the coroutine, which we can then justify what to do with it, and even call other functions from 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!"); } )); 

It may come in handy for you. http://answers.unity3d.com/questions/744888/returning-an-ienumerator-as-an-int.html

+7
source

All Articles