在Unity中是一个异步还是同步的WWW类?

时间:2015-12-15 23:42:45

标签: asynchronous unity3d

我想了解如何在Unity中编写WWW调用。根据这里的描述http://docs.unity3d.com/ScriptReference/WWW.html我可以检查isDone属性,但在同一页面的示例中,它不会尝试检查isDone。

我的问题是,如果我拨打WWW电话并且需要几秒钟才能回复,游戏是否会冻结?

我想认为正确的代码是这样的,但是它呢?

StartCoroutine(WaitForResponse(myWWWObject));

private IEnumerator WaitForResponse(WWW aRequest ) {

    while ( ! aRequest.isDone )
        yield return aRequest;

}

游戏是否冻结直到aRequest完成?还是真的异步?

3 个答案:

答案 0 :(得分:1)

你需要了解Coroutines - Unity的一个基本功能,它允许你编写长时间的代码函数(例如:比框架长一些)冻结你的游戏。

http://docs.unity3d.com/Manual/Coroutines.html

在C#中,您可以发现协程函数,因为它的返回类型为IEnumerator。您可以在代码中找到函数将暂停的位置,并通过C#关键字yield再次继续。

每个MonoBehaviour类都可以管理协同程序,如果你告诉它使用StartCoroutine()启动协同程序,那么MonoBehaviour将每帧调用协程(有时多一次),直到Coroutine到达终点。

对于WWW类(支持协同例程),您只需要调用它:

  WWW www = new WWW(url);
  yield return www;

您创建一个带有要检索的URL的WWW类,并且MonoDevelop协程管理器将自动地每帧调用yield,直到www对象说它已完成(成功或失败)。

在此期间,您的游戏根本不会冻结。

答案 1 :(得分:0)

WWW的链接文档页面中,以下方法是协程方法:

IEnumerator Start() {
    WWW www = new WWW(url);
    yield return www;
    Renderer renderer = GetComponent<Renderer>();
    renderer.material.mainTexture = www.texture;
}

yield语句用于暂停执行并将控制权返回给Unity,然后在下一个游戏框架中继续执行。例如yield return null;将导致执行在下一帧中恢复。此外,您可以使用派生自YieldInstruction类的其中一个类来扩展该行为,例如WaitForSeconds

考虑yield return new WaitForSeconds(1f); - 这将在游戏时间过去1秒后恢复执行。 WWW类以类似的方式工作。您可以使用该类的实例来执行,仅在下载完成后返回,无需手动轮询isDone属性。

请记住,您只能在Coroutines中屈服,我建议您阅读它们。如果您想要在Coroutine中执行WWW请求,则必须手动轮询isDone并在完成后继续。

回答最后一个问题:在创建WWW类的实例时,游戏会冻结吗? - 不。该课程以异步方式工作。您可以在正常的更新/启动等功能中使用它,在Coroutines中使用yield。

答案 2 :(得分:-1)

如果我拨打WWW电话并且需要几秒钟才能回复,游戏是否会冻结? 不,游戏将不会freez尝试此代码,你会看到日志“corou”将立即显示即使图片正在下载。

public class WWWDemo : MonoBehaviour {
    bool b = true;
    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update()
    {
        if (b) {
            StartCoroutine(ExampleCoroutine());
            Debug.LogWarning("after corou");
        }

    }

    IEnumerator ExampleCoroutine()
    {
        b = false;
        Debug.Log("Time : " + DateTime.Now);
        string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";
        WWW www = new WWW(url);
        yield return www;
        Debug.Log("Time : " + DateTime.Now);
        Renderer render = gameObject.GetComponent<Renderer>();
        render.material.mainTexture = www.texture;
        Debug.Log("Time : " + DateTime.Now);

    }
}

但下一行的执行肯定会在收益率返回www语句后停止,它会等待图片下载,而Unity的其余事件将执行 async

单独考虑以下示例。启动事件执行它将等待的事件,但更新将持续运行。

 IEnumerator Start() { 
        Debug.Log("Time : " + DateTime.Now);
        string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";
        WWW www = new WWW(url);
        yield return www;
        Debug.Log("Time : " + DateTime.Now);
        Renderer render = gameObject.GetComponent<Renderer>();
        render.material.mainTexture = www.texture;
        Debug.Log("Time : " + DateTime.Now);
    }
void Update()
    {
            Debug.Log("update is running while start is waiting for downloading");        
    }