【问题标题】:How to read value from firebase in Unity?如何从 Unity 中的 firebase 读取值?
【发布时间】:2020-09-28 20:56:00
【问题描述】:

我真的不明白如何从 firebase 读取任何值。在谷歌文档中,据说我需要使用 GetValueAsync().ContinueWith(),但它的工作原理相当奇怪。所以,如果我使用:

FirebaseDatabase.DefaultInstance.GetReference("Leaders").GetValueAsync().ContinueWith(task => {
    if (task.IsFaulted) {
      Debug.Log("error");
    }
    else if (task.IsCompleted) {
      DataSnapshot snapshot = task.Result;
      Debug.Log(snapshot.Value.ToString());
    }
  });

然后它打印真实值,一切正常。但是,如果我试图找到一个具有此名称的 GameObject,则不会发生任何事情。

else if (task.IsCompleted) {
  DataSnapshot snapshot = task.Result;
  Debug.Log(GameObject.Find(snapshot.Value.ToString()).name);
} 

它不打印任何东西。它停在这条线上,但没有任何错误或消息。每次我尝试使用快照时都会发生这个问题。一个非常简单的事情,但我无法想象有什么问题?请帮忙。

【问题讨论】:

    标签: c# firebase unity3d firebase-realtime-database


    【解决方案1】:

    wrote an articlerecorded a video 在 Unity 中处理多任务处理,如果您对所有选项感到好奇,一定要查看这些内容。

    具体针对您的问题,我建议将ContinueWith 更改为ContinueWithOnMainThread。这是替代品的下降。

    FirebaseDatabase.DefaultInstance.GetReference("Leaders").GetValueAsync().ContinueWithOnMainThread(task => {
        if (task.IsFaulted) {
          Debug.Log("error");
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          Debug.Log(snapshot.Value.ToString());
        }
      });
    

    这让我解释了正在发生的事情:

    Firebase 和 Unity 的棘手之处在于 Firebase 倾向于在后台线程上执行工作,以避免长时间运行网络操作阻塞您的游戏。与Unity's UnityWebRequest 之类的 API 不同,开发人员需要确定如何以及何时将逻辑移回游戏线程。这意味着如果您想在后台使用此操作的结果进行更多工作,您可以,但这也意味着如果您在继续中开始执行非线程安全操作,您将面临非常意外的行为。

    Unity 保护某些函数(例如 GameObject.Find)免于后台线程中的访问——当它检测到不正常的情况时通常会引发异常。 ContinueWith 将在长时间运行的任务完成的任何地方开始执行,而ContinueWithOnMainThread 会将您的延续逻辑推送到在主线程上执行的队列中。这通常很有效,并且可以确保您在 continuation 中执行的任何 Unity 逻辑都在预期的时间发生。

    您可以选择通过以下方式将任务转换为coroutine

    var task = FirebaseDatabase.DefaultInstance.GetReference("Leaders").GetValueAsync();
    yield return new WaitUntil(()=>task.IsComplete);
    if (task.Exception) {
        // something bad happened, handle it
        yield break;
    }
    var snapshot = task.Result;
    

    这将使您能够更好地控制您的逻辑在游戏中的执行位置,并提供更多的内存安全性。您还可以使用 async/await 使代码看起来更像典型的 C#。

    【讨论】:

    • 谢谢!现在 GameObject.Find() 可以工作了,这很棒。但是我还有一个问题,如果你看一下我会很高兴link
    猜你喜欢
    • 1970-01-01
    • 2023-01-16
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2018-12-02
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多