【问题标题】:Unity - www.isDone always return falseUnity - www.isDone 总是返回 false
【发布时间】:2020-11-20 12:05:47
【问题描述】:

自上周以来,我一直在寻找解决方案,但我尝试的所有解决方案均无效。

我正在尝试做一件看起来很简单的事情。在 WebGL 模式下,我需要停止游戏执行,直到收到来自服务器的响应。我需要这个,因为如果发送的试探失败,我必须向玩家显示一条消息。

我试图通过使用WWW 类和IEnumerator 方法来做到这一点。我无法通过调用StartCoroutine 来启动IEnumarator 方法,因为这样做会立即开始执行下一行。所以我只是声明了一个 IEnumerator 类型的变量并调用了MoveNext 方法。

按照我的方法:

public class ServerOperations
{
    //...
    private int failed;

    public void RegisterPlay()
    {
        //...
        IEnumerator e = uploadFile(resultsFileName, resultsFileContent);
        while (e.MoveNext());
        //...
    }

    IEnumerator uploadFile(string fileName, string contentFile)
    {
        //...
        WWW www = new WWW(URL, formData);
        yield return www;
    
        while (!www.isDone)
        {
            Debug.Log("Not done");
            yield return true;
        }
    
        if (www.error != null) {
            Debug.Log ("file " + fileName + " w.error = " + www.error);
            failed = 1;
        }
        else
        {
            failed = 0;
        }
    }
}

文件已发送,但www.isDone 从未变为true,并且游戏因内存不足异常而崩溃。

我在我的实现中关注这个post

为什么我的服务器收到了文件,而www.isDone 永远不会成为真的?

【问题讨论】:

  • 从未使用过该库,但在 WWW 的文档中(除了说它现在已经过时),它说属性 .isDone 会在文件下载完成时更改,但从我可以阅读您的问题,您实际上是在将文件上传到服务器,对吗?

标签: c# unity3d coroutine ienumerator


【解决方案1】:

我马上就可以看到这里有 2 个问题。

首先,WWW 类已过时。你应该使用的是 UnityWebRequest。查看here,我认为这个示例完全符合您的要求。

其次,uploadFile 是一个协程,看起来你是在非协程上下文中运行它,通常应该只是跳过执行,什么都不做,所以很奇怪你说你设法上传了一些东西。无论如何,你应该做的是用 StartCoroutine 运行它。这将导致异步启动它。在 Update() 回调中,您可以检查您的操作是否已完成。

 private WWW www = null; // Make sure to declare it outside the function

 public void RegisterPlay() {
     StartCoroutine(uploadFile(...));
     .....
 }

 private void Update() {
     if (www && www.isDone) {
         www = null; // Zero it to avoid double completion
         // Here you know it is done, continue your code
     }
 }

【讨论】:

  • 这个解决方案的问题是我需要在上传未完成时停止程序。调用StartCoroutine(uploadFile(...)) 下一行开始执行。
  • 这不是问题。您不能将协程作为常规函数调用,句号将不起作用。如果你想暂停该代码直到协程完成,调用它的代码应该是协程本身。或者,您可以使用 start couroutine 并检查它是否已从 Update() 函数完成。
  • 我该怎么做?检查协程是否完成?
  • 我添加了一些示意图示例,请参阅答案。我还建议您阅读有关协程的内容以确保您了解其原理,这里有一篇好文章gamedevbeginner.com/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 2016-07-20
  • 2021-11-05
  • 2018-11-05
  • 2019-05-06
  • 2017-04-29
相关资源
最近更新 更多