Unità: è necessario restituire il valore solo al termine della coroutine

Sto lavorando a un gioco in unità e ho riscontrato un problema che non riesco a risolvere. Mi sto collegando a un server web tramite un object WWW standard e utilizzando una coroutine per eseguire una richiesta POST.

Il codice in sé funziona, ma ho bisogno di aggiornare un valore variabile e restituire quella variabile una volta terminata la coroutine, che non sono in grado di fare.

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

La coroutine aggiorna il valore di ‘success_fail’ con il valore pertinente. Ma il ‘return success_fail;’ la riga nel metodo POST viene eseguita prima della fine della coroutine, il che fa sì che restituisca un valore falso.

Ho provato ad usare una coroutine aggiuntiva ma, senza successo, suppongo di avere anche un errore. Come posso restituire il valore ‘success_fail’ solo al termine della coroutine?

Grazie.

    Solo una Coroutine può attendere un’altra Coroutine. Poiché è necessario attendere la coroutine che hai avviato (WaitForRequest), significa che devi convertire POST in una coroutine e non sarà in grado di restituire int.

    Sembra che success_fail sia una variabile membro, quindi se è esposto a chiunque abbia avviato POST (come una coroutine), non è necessario restituirlo comunque.

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

    In sostanza, se vuoi che il tuo codice “aspetti”, deve essere una coroutine. Non è ansible effettuare una chiamata che attende senza bloccare l’intero motore (senza alcun tipo di modifica del ciclo).

    Questo thread fornisce un modo in cui è ansible restituire int dalla tua coroutine se è davvero necessario, ma POST non può ancora essere una chiamata bloccante …

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

    Le funzioni non aspettano le coroutine prima del ritorno, tuttavia potresti usare un’azione per dare un qualche tipo di ritorno.

    Metti questo nella tua funzione Start

     WWW www = new WWW("http://google.com"); StartCoroutine(WaitForRequest(www,(status)=>{ print(status.ToString()); })); 

    e aggiungi questo.

     private IEnumerator WaitForRequest(WWW www,Action 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); } 

    Prova, anche se la funzione può modificare un valore, non restituisce un valore e ha un solo parametro. Quindi, in sostanza, questa non è una soluzione per restituire la tua coroutine, ma una volta ricevuto l’int dalla coroutine siamo quindi in grado di giustificare cosa fare con esso e persino chiamare altre funzioni dall’interno del callback.

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

    Questo potrebbe esserti utile. http://answers.unity3d.com/questions/744888/returning-an-ienumerator-as-an-int.html