You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity接入Firebase实现登录时ContinueWith内除Debug外功能不生效

问题根源

Firebase的异步方法(比如SignInWithEmailAndPasswordAsync)的ContinueWith回调默认运行在后台线程,而Unity规定所有UI修改、场景加载、Unity核心API调用都必须在主线程执行。Debug.Log是线程安全的所以可以正常输出,其他操作自然不会生效,部分情况还会触发静默报错。

解决方案

方案1:使用Firebase官方提供的ContinueWithOnMainThread(推荐)

Firebase Unity SDK专门封装了主线程调度的扩展方法,直接替换原来的ContinueWith即可,无需额外写工具类。
修改后代码如下:

public void Login()
{
    string email = emailInputField.text;
    string password = passwordInputField.text;
    // 把ContinueWith替换为ContinueWithOnMainThread
    auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWithOnMainThread(
        task =>
        {
            if (task.IsCompleted && !task.IsCanceled && !task.IsFaulted)
            {
                Debug.Log("[Login Success] ID: " + auth.CurrentUser.UserId);
                PlayerInformation.auth = auth;
                SceneManager.LoadScene("SongSelectScene");
            }
            else
            {
                messageUI.text = "[Login Failed] Please check your account";
                Debug.Log("[Login Failed] Please check your account");
            }
        });
}

方案2:自定义主线程调度器(适配旧版SDK)

如果你的Firebase SDK版本较低没有内置ContinueWithOnMainThread,可以自己实现一个主线程调度工具:

  1. 新建MainThreadDispatcher单例类,挂载到常驻场景的物体上:
using System;
using System.Collections.Generic;
using UnityEngine;

public class MainThreadDispatcher : MonoBehaviour
{
    public static MainThreadDispatcher Instance;
    private readonly Queue<Action> _executionQueue = new Queue<Action>();

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    private void Update()
    {
        lock (_executionQueue)
        {
            while (_executionQueue.Count > 0)
            {
                _executionQueue.Dequeue().Invoke();
            }
        }
    }

    public void Enqueue(Action action)
    {
        lock (_executionQueue)
        {
            _executionQueue.Enqueue(action);
        }
    }
}
  1. 回调中将需要主线程执行的代码丢到调度器队列:
public void Login()
{
    string email = emailInputField.text;
    string password = passwordInputField.text;
    auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(
        task =>
        {
            // 把所有Unity API操作放到主线程调度
            MainThreadDispatcher.Instance.Enqueue(() =>
            {
                if (task.IsCompleted && !task.IsCanceled && !task.IsFaulted)
                {
                    Debug.Log("[Login Success] ID: " + auth.CurrentUser.UserId);
                    PlayerInformation.auth = auth;
                    SceneManager.LoadScene("SongSelectScene");
                }
                else
                {
                    messageUI.text = "[Login Failed] Please check your account";
                    Debug.Log("[Login Failed] Please check your account");
                }
            });
        });
}
额外注意事项
  • 请提前确认SongSelectScene已经添加到Unity的Build Settings > Scenes In Build列表中,否则场景加载也会失败
  • 优先使用方案1,实现简单且不会有自定义调度器的潜在线程安全问题

内容的提问来源于stack exchange,提问作者tesSer-16

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 20:09:04