0
votes

I'm trying to build a Unity game on android/iOS by checking the development build option (so that I can use the profiler for debugging), but the SceneManager.LoadScene function doesn't work. I tried the scene name and index as the function parameters, but both didn't work.

It's important to note that the game works perfectly fine if I uncheck the development build option. I'm currently using Unity 2019.3.5.f1.

enter image description here

Edit:
I noticed that the scene loads without any problems when I run SceneManager.LoadScene from the Start() function. However, in most parts of my code, I run SceneManager.LoadScene from inside other functions, such as event handlers.

Here are a few code examples:

  1. I run this function in Awake(). It reaches SceneManager.LoadScene("Credentials"); then stops:
private void ConfirmGooglePlayerServicesRequirements()
    {
        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 = Firebase.FirebaseApp.DefaultInstance;

                InitializeFirebase();

                if (!signedIn)
                    SceneManager.LoadScene("Credentials");

            }
            else
            {
                Debug.LogError(System.String.Format(
                  "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
                // Firebase Unity SDK is not safe to use here.
            }
        });
    }
  1. This is a Firebase function which is called whenever a user signs in/out. It invokes an event called signedInEvent, which is handled by a function in another script that runs SceneManager.LoadScene.
void AuthStateChanged(object sender, System.EventArgs eventArgs)
    {
        if (auth.CurrentUser != user)
        {
            signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
            if (!signedIn && user != null)
            {
                Debug.Log("Signed out " + user.UserId);
            }
            user = auth.CurrentUser;
            if (signedIn)
            {
                Debug.Log("Signed in " + user.UserId);

                displayName = user.DisplayName ?? "";
                emailAddress = user.Email ?? "";
                userId = user.UserId ?? "";
                signedInEvent.Invoke(displayName, emailAddress, userId);
            }
        }
    }

Notes:

  • Scenes/FirstScene is enabled. It was disabled when I took the screenshot above because I was doing some tests.
  • I got this error using adb (android debug bridge) a while ago when I ran the game in development mode. It might be related to this issue: FindGameObjectWithTag can only be called from the main thread

Thanks!

1
Does show any error log? - TimChang
@TimChang adb didn't show any errors - Mohamed
Are you talking about FirstScene? It is disabled .. in general please add your code of what you are trying. - derHugo
@derHugo No, I'm talking about running LoadScene from any script. The game works without any issues if I uncheck development build. But in that case, I won't be able to use the profiler. - Mohamed
So show your code you are using to run this from a script ... - derHugo

1 Answers

1
votes

FindGameObjectWithTag can only be called from the main thread

This is indeed related! Now that you posted your code:

ContinueWith might get called on a background thread. Most of the Unity API may only be called from the main thread otherwise it might either show an error such as the one you mentioned or sometimes it just fails silently.


In general this is often solved by something like e.g. UnityMainThreadDispatcher.

However, specifically for Firebase there already exists an extension called ContinueWithOnMainThread in the Firebase.Extensions namespace which makes sure the callback code is actually executed in the main thread where the Unity API works.

Extension methods for System.Threading.Tasks.Task and System.Threading.Tasks.Task<T> that allow the continuation function to be executed on the main thread in Unity.

using Firebase.Extensions;

private void ConfirmGooglePlayerServicesRequirements()
{
    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 = Firebase.FirebaseApp.DefaultInstance;

            InitializeFirebase();

            if (!signedIn)
            {
                SceneManager.LoadScene("Credentials");
            }
        }
        else
        {
            Debug.LogError($"Could not resolve all Firebase dependencies: {dependencyStatus}", this);
            // Firebase Unity SDK is not safe to use here.
        }
    });
}