因此,当我尝试从Firebase RealTime数据库获取数据时,数据被成功接收。但是,当我尝试更改场景时,脚本只是停止工作。这是我的完整脚本:
using Firebase;
using Firebase.Database;
using Firebase.Extensions;
using Firebase.Unity.Editor;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class NewBehaviourScript : MonoBehaviour
{
DependencyStatus dependencyStatus = DependencyStatus.UnavailableOther;
protected bool isFirebaseInitialized = false;
// Start is called before the first frame update
private void Start()
{
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
dependencyStatus = task.Result;
if (dependencyStatus == DependencyStatus.Available)
{
InitializeFirebase();
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + dependencyStatus);
}
});
}
protected virtual void InitializeFirebase()
{
FirebaseApp app = FirebaseApp.DefaultInstance;
// NOTE: You'll need to replace this url with your Firebase App's database
// path in order for the database connection to work correctly in editor.
app.SetEditorDatabaseUrl("https://frim-exam.firebaseio.com/");
if (app.Options.DatabaseUrl != null)
app.SetEditorDatabaseUrl(app.Options.DatabaseUrl);
StartListener();
isFirebaseInitialized = true;
}
void StartListener()
{
FirebaseDatabase.DefaultInstance
.GetReference("Leaders")
.GetValueAsync().ContinueWith(task => {
if (task.IsFaulted)
{
// Handle the error...
}
else if (task.IsCompleted)
{
DataSnapshot snapshot = task.Result;
// Do something with snapshot...
Debug.Log("Done!");
SceneManager.LoadSceneAsync("Scene2");
Debug.Log("Done!!!");
}
});
}
}
当我运行此脚本时,仅显示“完成!”。在日志控制台上登录。更改场景脚本及其下的脚本,例如,我想写日志“ Done !!!”(完成!!!)场景更改后,不执行。
答案 0 :(得分:1)
为什么不使用DontDestroyOnLoad在不同场景之间保留代码?因为新场景的加载会破坏所有当前的场景对象。对于这种情况,您可以尝试以下代码吗?
using Firebase;
using Firebase.Database;
using Firebase.Extensions;
using Firebase.Unity.Editor;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
private static bool created = false;
// the belowing code is used for changing the scene without losing the script
void Awake()
{
if (!created)
{
DontDestroyOnLoad(this.gameObject);
created = true;
Debug.Log("Awake: " + this.gameObject);
}
}
public class NewBehaviourScript : MonoBehaviour
{
DependencyStatus dependencyStatus = DependencyStatus.UnavailableOther;
protected bool isFirebaseInitialized = false;
// Start is called before the first frame update
private void Start()
{
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
dependencyStatus = task.Result;
if (dependencyStatus == DependencyStatus.Available)
{
InitializeFirebase();
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + dependencyStatus);
}
});
}
protected virtual void InitializeFirebase()
{
FirebaseApp app = FirebaseApp.DefaultInstance;
// NOTE: You'll need to replace this url with your Firebase App's database
// path in order for the database connection to work correctly in editor.
app.SetEditorDatabaseUrl("https://frim-exam.firebaseio.com/");
if (app.Options.DatabaseUrl != null)
app.SetEditorDatabaseUrl(app.Options.DatabaseUrl);
StartListener();
isFirebaseInitialized = true;
}
void StartListener()
{
FirebaseDatabase.DefaultInstance
.GetReference("Leaders")
.GetValueAsync().ContinueWith(task => {
if (task.IsFaulted)
{
// Handle the error...
}
else if (task.IsCompleted)
{
DataSnapshot snapshot = task.Result;
// Do something with snapshot...
Debug.Log("Done!");
SceneManager.LoadSceneAsync("Scene2");
Debug.Log("Done!!!");
}
});
}
}
答案 1 :(得分:1)
这是Unity中使用Firebase的经典任务延续问题。使用ContinueWith
时,不能确保在Unity主线程上调用它。您要SceneManager.LoadSceneAsync()
进行的操作需要在Unity主线程上执行。如果您尝试访问ContinueWith
内部的GameObjects,那么即使那样也会失败。代码只是隐藏了出来,在控制台中没有任何错误。
解决方案:
正是出于这个原因而使用ContinueWithOnMainThread
中的Firebase extensions,而不是ContinueWith
。
答案 2 :(得分:0)
因此,最好的答案可能就是尝试更新为latest version of the firebase SDK。我想为您提供帮助的特定修补程序是6.5.0:
FirebaseApp,FirebaseAuth,FirebaseDatabase,FirebaseFunctions,FirebaseInstanceId和FirebaseStorage的实例在创建后将一直保持活动状态,直到明确处置为止。
因此,就像在其他地方提到的那样,您可能只需要确保将脚本标记为DontDestroyOnLoad(gameObject);
,就可以基本告诉整个游戏对象(假设它位于场景的根),当它的父对象不消失时,场景变化。有关详细信息和注意事项,请参见Unity documentation。
我认为Firebase SDK也有所更改,可以为您提供帮助。每当您调用类似FirebaseApp.DefaultInstance
之类的内容时,Firebase都会对该对象进行一些延迟的初始化。与之类似,首先检查DefaultInstance
是否为空。如果是这样,请创建它并将其退回。这是典型的单例模式。
更改是出于各种原因,这曾经是一个较弱的参考。从6.5.0版开始,它已成为普通的C#参考(这意味着它被清理的可能性要小得多),可以摆脱“场景改变,某些东西停止工作”周围的许多错误。
除此以外,只需确保使用DontDestroyOnLoad
并确保它正在执行您期望的操作(即:将其应用于场景根源的游戏对象,而不是MonoBehaviour或子对象)。 / p>
-帕特里克