[英]Why is part of my code not executed if I enable/disable Unity gameObject?
我正在使用 PlayFab 並決定遷移到 Firebase。 我想使用 FirebaseAuth 在我的 Unity 游戲中實現登錄系統(並刪除了 PlayFab 代碼)。
所以我制作了一個 FirebaseManager.cs class,並修改了腳本執行順序,使其在任何其他自定義腳本之前運行。
我嘗試實現創建帳戶所需的內容,並且效果很好。 我知道 Firebase 默默地讓用戶在會話之間保持連接。 所以我想從我的“家庭場景”(這也是您登錄/創建帳戶的場景)檢查用戶是否已經連接。
public class FirebaseManager : MonoBehaviour
{
private static FirebaseManager _instance;
public static FirebaseManager Instance { ... }
private FirebaseApp _app;
private FirebaseAuth _auth;
public FirebaseAuth Auth
{
get
{
if (_auth == null)
{
_auth = FirebaseAuth.GetAuth(_app);
}
return _auth;
}
}
private FirebaseUser _user;
public FirebaseUser User
{
get
{
return _user;
}
set
{
_user = value;
}
}
// Events to subscribe to for this service
public delegate void FirebaseInitialized();
public static event FirebaseInitialized OnFirebaseInitialized;
private void Awake()
{
if (_instance == null)
{
DontDestroyOnLoad(this.gameObject);
_instance = this;
InitializeFirebase();
}
else { Destroy(this.gameObject); }
}
private void InitializeFirebase()
{
Debug.Log($"FirebaseManager.cs > INITIALIZING FIREBASE");
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
_app = FirebaseApp.DefaultInstance;
// Create and hold a reference to FirebaseAuth
_auth = FirebaseAuth.DefaultInstance;
// Create and hold a reference to already logged in user (if any)
_user = _auth.CurrentUser;
if (OnFirebaseInitialized != null) OnFirebaseInitialized.Invoke();
}
else
{
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
// Firebase Unity SDK is not safe to use here.
}
});
}
private void OnDestroy()
{
if (_auth != null) _auth = null;
}
}
我還做了一個 static AuthService.cs class 從我的場景中調用:
public static class AuthService
{
private static FirebaseAuth auth = FirebaseManager.Instance.Auth;
public static bool IsUserAlreadyLoggedIn()
{
Debug.Log($"AuthService.cs > Checking if user already logged in");
return auth.CurrentUser != null;
}
}
然后在我的登錄場景中,我有這個 LoginManager.cs class:
public class LoginManager : MonoBehaviour
{
// Loading Animation
[Header("Loading Animation")]
public GameObject loadingAnimation;
private void Awake()
{
FirebaseManager.OnFirebaseInitialized += OnFirebaseInitialized;
}
private void Start()
{
ShowLoadingAnimation(true);
}
private void OnFirebaseInitialized()
{
if (AuthService.IsUserAlreadyLoggedIn())
{
Debug.Log($"Already LoggedIn");
OnLoginSuccess();
}
else
{
Debug.Log($"No User LoggedIn");
ShowLoadingAnimation(false);
}
}
private void OnLoginSuccess()
{
ShowLoadingAnimation(false); // From here, no code is executed
Debug.Log($"Logged In as: {FirebaseManager.Instance.Auth.CurrentUser.Email}");
// SceneLoader.Instance.Load(SceneLoader.Scene.CharacterCreation);
}
private void OnDestroy()
{
FirebaseManager.OnFirebaseInitialized -= OnFirebaseInitialized;
}
/// <summary>
/// Show or Hide the Loading Animation
/// </summary>
/// <param name="show">True = show || False = hide</param>
private void ShowLoadingAnimation(bool show)
{
loadingAnimation.SetActive(show);
}
}
正在加載的 animation 游戲對象只是一個動畫圖像(+ 另一個用於阻止用戶輸入的圖像)。
每當代碼到達ShowLoadingAnimation()方法時。 之后的所有代碼都沒有執行。 但是,如果我刪除所有對ShowLoadingAnimation()的調用,一切正常。 同樣的邏輯在 PlayFab 上運行良好。
我只是不明白發生了什么。 也許與線程有關? 或者也許只是我的 Firebase 實現是錯誤的? 我能做些什么?
謝謝。
一種解釋是 OnFirebaseInitialized 在后台線程上被調用。
Unity 的 MonoBehaviour 系統不是線程安全的,因此如果從后台線程將 GameObject 設置為非活動狀態,這可能會導致異常和代碼執行停止。
為了避免這個問題,您可以讓 OnLoginSuccess 只需將 boolean 變量設置為 true,然后在 Update 方法(在主線程上調用)檢查此變量何時為 true 並調用 ShowLoadingAnimation(false)。
您還應該只在 lock 語句中訪問此 boolean 變量以確保線程安全。
所以我找到了解決方案。 正如 Sisus 所說(感謝您的回答,它在我的 Google 搜索中幫助了我),這個問題是由在另一個線程而不是主線程上運行的代碼引起的。
根據這個Firebase 視頻,在初始化 Firebase 時,我可以調用ContinueWithOnMainThread
而不是簡單地ContinueWith
來解決該問題。
(請注意,這需要using Firebase.Extensions
,請參閱Firebase.Extensions.TaskExtension 文檔)
所以更新后的 Firebase 初始化看起來像這樣:
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
{
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
_app = FirebaseApp.DefaultInstance;
// Create and hold a reference to FirebaseAuth
_auth = FirebaseAuth.DefaultInstance;
// Create and hold a reference to already logged in user (if any)
_user = _auth.CurrentUser;
if (OnFirebaseInitialized != null) OnFirebaseInitialized.Invoke();
}
else
{
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}", dependencyStatus));
// Firebase Unity SDK is not safe to use here.
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.