Unity - 只需在协同程序完成后返回值

时间:2015-05-15 19:41:57

标签: c# unity3d coroutine

我在团结游戏中工作,遇到了一个我无法解决的问题。 我通过标准的WWW对象连接到Web服务器并使用协程来执行POST请求。

代码本身有效,但我需要更新变量值并在协程完成后返回该变量,这是我无法做到的。

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'具有相关价值。 但是'返回success_fail;' POST方法中的行在协同程序完成之前运行,这会导致它返回false值。

我试图使用额外的协程,但没有成功,假设我也有错误。 我怎样才能归还成功'在协程完成后才有价值?

感谢。

3 个答案:

答案 0 :(得分:12)

函数不会在返回之前等待协同程序,但是你可以使用Action来提供某种返回。

将其放入“开始”功能

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);
}

尝试一下,虽然该函数可以更改一个值,但它不会返回一个值而只有一个参数。所以实际上这并不是一个返回你的协同程序的解决方案,但是一旦从协程程序接收到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

答案 1 :(得分:2)

只有一个协程可以等待另一个协同程序。由于你需要等待你开始的协程(WaitForRequest),这意味着你必须将POST转换为协同程序并且它不能返回int。

看起来success_fail是一个成员变量,所以如果它暴露给任何开始POST的人(作为协程),你无论如何都不需要返回它。

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;
    }    
}

基本上,如果你想让你的代码等待&#34;它必须是一个协程。你不能在不阻塞整个引擎的情况下进行等待的呼叫(没有某种类型的循环破解)。

这个帖子提供了一种方法,如果你真的需要,你可以从你的协程中返回int,但是POST仍然不能成为阻塞调用......

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

答案 2 :(得分:0)

https://stackoverflow.com/a/67805727/13098229 请参考此网页请求

并且不要使用 WWW 而是使用 UnityWebRequest