gpt4 book ai didi

firebase - Unity3d 与 Firebase : Can't Start Coroutine

转载 作者:行者123 更新时间:2023-12-05 07:07:39 25 4
gpt4 key购买 nike

问候,

我目前遇到协程无法启动的问题。这是我第一次遇到这个问题,我在网上找不到合适的解决方案。如果有人能指出解决此问题的正确方向,我将不胜感激。

这是代码。

path_reference.GetDownloadUrlAsync().ContinueWith((Task<Uri> task) => {

if (!task.IsFaulted && !task.IsCanceled)
{
Debug.Log("Download URL: " + task.Result);

StartCoroutine(DownloadStuff(task.Result));
}
else
{
Debug.Log(task.Exception.ToString());
}
});
}
IEnumerator DownloadStuff(Uri uri)
{
Debug.Log("Start Download");

using (var www = UnityWebRequestTexture.GetTexture(uri))
{
yield return www.SendWebRequest();

if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
var texture = DownloadHandlerTexture.GetContent(www);

//Texture2D texture = new Texture2D(1, 1);

//if you need sprite for SpriteRenderer or Image
Sprite sprite = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width,
texture.height), new Vector2(0.5f, 0.5f), 100.0f);
Debug.Log("Finished downloading!");
}

Debug.Log(www.downloadProgress);
}
}'

最佳答案

Firebase返回的任务很可能在主线程以外的线程执行完毕,Unity协程只能在主线程运行。

Unity 对多线程和异步的支持参差不齐,包括如果这些错误的延续将在主线程以外的另一个线程上执行,则“吃掉”一些错误。

要解决此问题,您需要更改启动协程的函数:

try {
// Important: ConfigureAwait(true) ensures the code after this will run in the
// same thread as the code before (which is the main thread!)
var url = await path_reference.GetDownloadUrlAsync().ConfigureAwait(true);
StartCoroutine(DownloadStuff(url));
} catch (Exception ex) {
// Tip: when logging errors, use LogException and pass the whole exception,
// that way you will get pretty links to the error line in the whole stack trace.
Debug.LogException(ex);
}

顺便说一句,我通常在我的所有项目中都有一些扩展方法来处理这个问题,同时留在异步世界而不是协程世界(因为至少使用异步我可以捕获错误而不仅仅是“停止并捕获”像 Unity 的协同程序一样开火”

主要有:

public static Task ToTask(this YieldInstruction self, MonoBehaviour owner) {
var source = new TaskCompletionSource<object>();

IEnumerable Routine() {
yield return self;
source.SetResult(null);
}

return source.Task;
}

private static Task SendAsync(this UnityWebRequest self, MonoBehaviour owner) {
var source = new TaskCompletionSource<object>();

await self.SendWebRequest().ToTask(owner);

if (
self.isHttpError
|| self.isNetworkError
) {
source.SetException(new Exception(request.error));
yield break;
}

source.SetResult(null);
}

你可以像这样在 MonoBehaviour 中使用:

await new WaitForSeconds(0.2f).ToTask(this);

UnityWebRequest request = /* etc */;
await request.SendAsync(this);
var texture = DownloadHandlerTexture.GetContent(request);

请注意,这些方法不需要 ConfigureAwait,因为它们的 SetResult/SetException 调用是从 Unity 提供的协程延续运行的。

关于firebase - Unity3d 与 Firebase : Can't Start Coroutine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62060292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com