c# - 关于用于 Unity 和线程任务的新 Firebase SDK

标签 c# unity3d firebase firebase-realtime-database

我有一个关于 Unity C# 和全新 Firebase SDK 的更普遍的问题.我已经查看了所有新文档,但还没有看到答案。如果你从下面的数据库中检索数据,它不允许你在这个函数内执行像 Instantiate 这样的方法,因为它不会发生在主线程上。你会怎么做呢? TLDR 我想知道如何在从 Firebase 检索内容之后或同时执行游戏功能。

   FirebaseDatabase.DefaultInstance
    .GetReference("Scenes").OrderByChild("order")
    .ValueChanged += (object sender2, ValueChangedEventArgs e2) => {
      if (e2.DatabaseError != null) {
        Debug.LogError(e2.DatabaseError.Message);
        }
        scenes = asset.text.Split('\n');
        return;
      }
      if (e2.Snapshot != null && e2.Snapshot.ChildrenCount > 0) {
        sceneCollection.Clear();
        foreach (var childSnapshot in e2.Snapshot.Children) {
          var sceneName = childSnapshot.Child("name").Value.ToString(); 
          sceneCollection.Add( new SceneItem(sceneName, 0));

          // I WANTED TO INSTANTIATE SOMTHING HERE

        }

      }
    };

最佳答案

(来自 Firebase 团队的 Ben)

现在这个问题已经解决了,Stewart 在下面说:

https://firebase.google.com/support/release-notes/unity#1.0.1

我将保留下面的代码,以防有人发现能够从后台线程编码到 ui 线程很有用。安装此同步上下文后,您可以像使用任何其他 .Net SynchronizationContext 一样使用它:

https://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext(v=vs.110).aspx

UnitySynchronizationContext.Install();

class UnitySynchronizationContext : SynchronizationContext {
  static UnitySynchronizationContext _instance = null;
  GameObject gameObject;
  Queue<Tuple<SendOrPostCallback, object>> queue;

  private UnitySynchronizationContext() {
    gameObject = new GameObject("SynchronizationContext");
    gameObject.AddComponent<SynchronizationContextBehavoir>();
    queue =
      gameObject.GetComponent<SynchronizationContextBehavoir>()
        .Queue;
  }

  public static void Install() {
    if (SynchronizationContext.Current == null)
    {
      if (_instance == null)
      {
        _instance = new UnitySynchronizationContext();
      }
      SynchronizationContext.SetSynchronizationContext(_instance);
    }
  }

  public override void Post(SendOrPostCallback d, object state) {
    lock (queue)
    {
      queue.Enqueue(new Tuple<SendOrPostCallback, object>(d, state));
    }
  }

  class SynchronizationContextBehavoir : MonoBehaviour {
    Queue<Tuple<SendOrPostCallback, object>> callbackQueue
        = new Queue<Tuple<SendOrPostCallback, object>>();

    public Queue<Tuple<SendOrPostCallback, object>>
        Queue { get { return callbackQueue; }}

    IEnumerator Start() {
      while (true)
      {
        Tuple<SendOrPostCallback, object> entry = null;
        lock (callbackQueue)
        {
          if (callbackQueue.Count > 0)
          {
            entry = callbackQueue.Dequeue();
          }
        }
        if (entry != null && entry.Item1 != null)
        {
          try {
            entry.Item1(entry.Item2);
          } catch (Exception e) { 
            UnityEngine.Debug.Log(e.ToString());
          }
        }
        yield return null;
      }
    }
  }
}

关于c# - 关于用于 Unity 和线程任务的新 Firebase SDK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40558537/

相关文章:

unit-testing - 在 Unity3d 测试脚本中,如何从另一个类调用静态函数?

GitHub 一直抛出 "Could not commit submodules"错误,我不明白这是为什么。有任何想法吗?

swift - 当 firebase 子项快速删除时,从本地字典中删除值

从 Firestore 查询数据的 Firebase 存储规则

unity3d - SceneManager 没有按名称获取场景

android - 为每个构建变体配置 Firebase Analytics + Google Tag Manager (GTM)

C#.NET 4.0 并发字典 : TryRemove within a lock?

c# - Sqlite 数据库和数据网格

c# - Xamarin.Forms无法从资源返回空读取文本文件

c# - 如何在不违反依赖注入(inject)的情况下为单个数据库使用多个上下文