Unity - need to return value only after coroutine finishes
我正在统一开发游戏,遇到了无法解决的问题。
我正在通过标准WWW对象并使用协程连接到Web服务器,以执行POST请求。
代码本身可以工作,但是我需要更新一个变量值,并在协程完成后返回该变量,而我无法执行此操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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; } } |
协程会使用相关值更新" success_fail"的值。
但是"返回成功失败"; 协程完成之前,POST方法中的代码行会运行,这会导致它返回错误的值。
我尝试使用其他协程,但未成功,假设我也有错误。
如何仅在协程完成后才能返回" success_fail"值?
谢谢。
函数不等待协程返回,但是您可以使用Action进行某种返回。
把它放在你的启动功能中
1 2 3 4 5 | WWW www = new WWW("http://google.com"); StartCoroutine(WaitForRequest(www,(status)=>{ print(status.ToString()); })); |
并添加它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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); } |
尝试一下,尽管函数可以更改值,但它不返回值,而只有一个参数。因此,从本质上讲,这不是返回协程的解决方案,但是,一旦从协程接收到int,我们便可以证明对其进行处理的理由,甚至可以从回调内调用其他函数。
1 2 3 4 5 6 7 | 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!"); } )); |
这可能对您有用。
http://answers.unity3d.com/questions/744888/returning-an-ienumerator-as-an-int.html
只有协程可以等待另一个协程。由于您需要等待启动的协程(WaitForRequest),因此这意味着您必须将POST转换为协程,并且它无法返回int。
看起来success_fail是成员变量,所以如果暴露给启动POST的人(作为协程),则无论如何都不需要返回它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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; } } |
基本上,如果您希望代码"等待",则必须是协程。您不能在不阻塞整个引擎的情况下进行等待(没有某种类型的循环攻击)的呼叫。
这个线程提供了一种方法,您可以在需要时从协程返回int,但是POST仍然不能成为阻塞调用...
http://answers.unity3d.com/questions/24640/how-do-i-return-a-value-from-a-coroutine.html