我想了解如何在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完成?还是真的异步?
答案 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");
}