关于用于 Unity 和线程任务的新 Firebase SDK
Posted
技术标签:
【中文标题】关于用于 Unity 和线程任务的新 Firebase SDK【英文标题】:Regarding the new Firebase SDK for Unity and Threading Tasks 【发布时间】:2017-03-26 07:22:27 【问题描述】:关于 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
;
【问题讨论】:
我还没查!但是如果你用谷歌搜索“Unity3D 回调到主线程”,你会发现很多关于这个例子的讨论......forum.unity3d.com/threads/mainthread-function-caller.348198...... 我建议从资产商店获取处理线程的(优秀)包之一;它将解决问题。令人惊讶的是 Firebase 没有“投入一些东西”来处理这个问题。 非常感谢 JB 我会试试的。另外,我将向 Firebase 团队提出功能请求。 对,很奇怪他们没有解决这个问题。很抱歉我没有机会看它;你很确定他们没有包含返回主线程的机制吗? BTW 在那个代码中你 += ... 我鼓励你在你的脚本中把它作为一个单独的函数,并且 += 那个函数 - 它只是更清楚到底发生了什么你知道吗? 【参考方案1】:(来自 Firebase 团队的 Ben)
正如斯图尔特所说,现在已修复:
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;
【讨论】:
嗨本杰明伍尔夫。你是说你在 Firebase 吗?? 我会试一试的。没有必要道歉。你做得很好。 感谢您发布此内容。 @BenjaminWulfe 抱歉,本杰明,请查看我在此问题的已接受答案上发表的评论。谢谢!【参考方案2】:我们已在 1.0.1 版本中修复了此问题: https://firebase.google.com/support/release-notes/unity#1.0.1
您可以从以下位置下载最新版本: https://firebase.google.com/docs/unity/setup
干杯,
Stewart(来自 Firebase 团队)
【讨论】:
嗨!我可以从 CreateUserWithEmailAndPasswordAsync 的回调中调用与统一相关的方法,但是如果我切换到 .net 4.6,然后执行 Assets->Play Services Resolver->Version Handler->Update 我得到“只能从主线程调用方法”。这是 .net 4.6 中的一个已知问题吗?我们需要自己处理线程同步吗?以上是关于关于用于 Unity 和线程任务的新 Firebase SDK的主要内容,如果未能解决你的问题,请参考以下文章