I have a more general question regarding Unity C# and the brand new Firebase SDK. I've looked through all of the new documentation and haven't seen an answer to this yet. If you retrieve data from the database below, it doesn't allow you to execute methods like Instantiate inside this function because it is not happening on the main thread. How would you go about doing this? TLDR I want to know how to execute game functions after or while retrieving stuff from 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
}
}
};
(Ben from the Firebase team here)
This is now fixed as Stewart says below:
https://firebase.google.com/support/release-notes/unity#1.0.1
I'm leaving the code below in case anyone finds it useful to be able to marshal to the ui thread from a background thread. Once you install this synchronizationcontext, you can use it like any other .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;
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With