StartCoroutine和IEnumerator(Unity 3D)

时间:2016-04-26 06:25:39

标签: c# unity3d ienumerator

这是我的代码

public void myFuntion(){
     JsonFx.Json.JsonWriter writer =new JsonFx.Json.JsonWriter();
     string jsondata2=writer.Write(fps);
     WWWForm form = new WWWForm();
     form.AddField("facprodstrans", jsondata2);
     string url="127.0.0.1/few/get_trans.php"; 
     www = new WWW(url,form);
     StartCoroutine(WaitForRequest(www));
     print ("<<<<<<<<<<<<<"+fpts.time_remaining);
 }
 IEnumerator WaitForRequest(WWW www){ 
     yield return www;
     string facpdata = www.text;
     JsonFx.Json.JsonReader reader = new JsonFx.Json.JsonReader ();
     fpts = reader.Read<FactoryProdTransS> (facpdata);
     print(">>>>>>>>>>>>>"+fpts.time_remaining);
 }  

函数'myFunction'中的print语句在IEnumerator中的print语句之前执行,因为它首先打印旧值,然后更新值,无法找出原因。

1 个答案:

答案 0 :(得分:3)

MyFunction启动,它命中一个StartCoroutine,这是一个方法,所以它跳转到那里。 那时MyFunction处于暂停状态。

Unity做了一些自己的事情,很少有人真正意识到,因为它发生在c ++方面。不知何故,你可以认为它将方法放在一个协程列表上。

它开始运行WaitForRequest内部的内容,直到找到yield。由于返回类型IEnumerator,预期产量。

当找到产量时,它退出协程并返回到它停止的位置,所以回到MyFunction并在StartCoroutine之后继续。在你的情况下它打印。

下一帧,Unity检查该协程的假设列表以查看是否有一些,在您的情况下它会找到WaitForRequest。它回到那里它先退出,收益率返回www; 。如果完成www,程序将进行咨询,如果没有,则与前一帧相同。如果完成了www,它会跳过yield并继续进行所有json解析。在协程结束时,我会假设编译器在协程列表上搜索该方法并将其删除,以便它不会再次发生。

如果您需要在协程完成后执行某个操作,则需要传递一个代理:

void OnComplete(){ Debug:Log("Done"); }

IEnumerator WaitForRequest(Action onComplete){ 
     WWW www = new WWW(url);
     yield return www;
     string facpdata = www.text;
     JsonFx.Json.JsonReader reader = new JsonFx.Json.JsonReader ();
     fpts = reader.Read<FactoryProdTransS> (facpdata);
     print(">>>>>>>>>>>>>"+fpts.time_remaining);
     onComplete();
 }

如果你需要从你的协程获得结果,最好传递一个代表:

IEnumerator WaitForRequest(Action<string> onComplete){ 
     WWW www = new WWW(url);
     yield return www;
     string facpdata = www.text;
     JsonFx.Json.JsonReader reader = new JsonFx.Json.JsonReader ();
     fpts = reader.Read<FactoryProdTransS> (facpdata);
     print(">>>>>>>>>>>>>"+fpts.time_remaining);
     onComplete(www.text);
 }

void Start(){
    string text= null;
    StartCoroutine(WaitForRequest(result=> text = result));
}