web-dev-qa-db-ja.com

Unity-コルーチンが終了した後にのみ値を返す必要があります

私は団結してゲームに取り組んでいて、解決できない問題に遭遇しました。標準の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」の値を関連する値で更新します。しかし、「returnsuccess_fail;」 POSTメソッドの行は、コルーチンが終了する前に実行されるため、誤った値が返されます。

追加のコルーチンを使用しようとしましたが、失敗しました。そこでもエラーが発生したと考えてください。コルーチンが終了した後にのみ「success_fail」値を返すにはどうすればよいですか?

ありがとう。

7
David Faizulaev

コルーチンだけが別のコルーチンを待つことができます。開始したコルーチン(WaitForRequest)を待つ必要があるため、POSTをコルーチンに変換する必要があり、intを返すことができなくなります。

Success_failはメンバー変数のように見えるので、starts 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;
    }    
}

基本的に、コードを「待機」させたい場合は、コルーチンである必要があります。エンジン全体をブロックせずに(何らかのループハックなしで)待機する呼び出しを行うことはできません。

このスレッドは、本当に必要な場合にコルーチンからintを返すことができる方法を提供しますが、POSTはそれでもブロッキング呼び出しにはなり得ません...

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

3
Ted Bigham

関数はコルーチンを待ってから戻ることはありませんが、アクションを使用して何らかのリターンを与えることができます。

これをスタート関数に入れてください

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

これを試してみてください。ただし、関数は値を変更できますが、値を返さず、パラメーターは1つしかありません。したがって、本質的にこれはコルーチンを返すためのソリューションではありませんが、コルーチンから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

14
Grimmdev