Unity - 仅在协程完成后才需要 return 值
Unity - need to return value only after coroutine finishes
我正在联合开发一款游戏,遇到了一个我无法解决的问题。
我正在通过标准 WWW 对象连接到 Web 服务器并使用协程来执行 POST 请求。
代码本身可以工作,但是我需要更新一个变量值,并且 return 协程完成后该变量,这是我无法做到的。
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 方法中的 'return success_fail;' 行在协程完成之前运行,这导致它 return 一个错误值。
我尝试使用额外的协程但没有成功,假设我在那里也有错误。
如何仅在协程完成后才能 return 'success_fail' 值?
谢谢。
只有协程可以等待另一个协程。由于你需要等待你启动的协程(WaitForRequest),这意味着你必须将 POST 转换为协程并且它无法 return int.
看起来 success_fail 是一个成员变量,所以如果它暴露给启动 POST 的任何人(作为协程),您无论如何都不需要 return .
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;
}
}
基本上,如果你想让你的代码"wait",它必须是协程。您无法在不阻塞整个引擎的情况下进行等待调用(没有某种类型的循环 hack)。
此线程提供了一种方法,如果您确实需要,您可以 return 来自协程的 int,但 POST 仍然不能成为阻塞调用...
http://answers.unity3d.com/questions/24640/how-do-i-return-a-value-from-a-coroutine.html
函数不会在 return 之前等待协程,但是您可以使用 Action 来提供某种 return.
将其放入您的开始功能
WWW www = new WWW("http://google.com");
StartCoroutine(WaitForRequest(www,(status)=>{
print(status.ToString());
}));
并添加这个。
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);
}
试一试,尽管该函数可以更改值,但它 return 没有值,只有一个参数。所以从本质上讲,这不是 returning 协程的解决方案,但是一旦从协程接收到 int,我们就可以证明如何处理它,甚至可以从回调中调用其他函数。
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
网络请求请参考此
并且不要使用 WWW
而是使用 UnityWebRequest
我正在联合开发一款游戏,遇到了一个我无法解决的问题。 我正在通过标准 WWW 对象连接到 Web 服务器并使用协程来执行 POST 请求。
代码本身可以工作,但是我需要更新一个变量值,并且 return 协程完成后该变量,这是我无法做到的。
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 方法中的 'return success_fail;' 行在协程完成之前运行,这导致它 return 一个错误值。
我尝试使用额外的协程但没有成功,假设我在那里也有错误。 如何仅在协程完成后才能 return 'success_fail' 值?
谢谢。
只有协程可以等待另一个协程。由于你需要等待你启动的协程(WaitForRequest),这意味着你必须将 POST 转换为协程并且它无法 return int.
看起来 success_fail 是一个成员变量,所以如果它暴露给启动 POST 的任何人(作为协程),您无论如何都不需要 return .
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;
}
}
基本上,如果你想让你的代码"wait",它必须是协程。您无法在不阻塞整个引擎的情况下进行等待调用(没有某种类型的循环 hack)。
此线程提供了一种方法,如果您确实需要,您可以 return 来自协程的 int,但 POST 仍然不能成为阻塞调用...
http://answers.unity3d.com/questions/24640/how-do-i-return-a-value-from-a-coroutine.html
函数不会在 return 之前等待协程,但是您可以使用 Action 来提供某种 return.
将其放入您的开始功能
WWW www = new WWW("http://google.com");
StartCoroutine(WaitForRequest(www,(status)=>{
print(status.ToString());
}));
并添加这个。
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);
}
试一试,尽管该函数可以更改值,但它 return 没有值,只有一个参数。所以从本质上讲,这不是 returning 协程的解决方案,但是一旦从协程接收到 int,我们就可以证明如何处理它,甚至可以从回调中调用其他函数。
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
并且不要使用 WWW
而是使用 UnityWebRequest