私は団結してゲームに取り組んでいて、解決できない問題に遭遇しました。標準の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」値を返すにはどうすればよいですか?
ありがとう。
コルーチンだけが別のコルーチンを待つことができます。開始したコルーチン(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
関数はコルーチンを待ってから戻ることはありませんが、アクションを使用して何らかのリターンを与えることができます。
これをスタート関数に入れてください
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