【问题标题】:UnityEngine.UI.Text is not updating inside async methodUnityEngine.UI.Text 没有在异步方法中更新
【发布时间】:2021-05-26 03:29:27
【问题描述】:

我有一个脚本 MenuManager.cs amd 我这个脚本我在 firebase firestone 中获得了两个文档,这很好用,但是当我将结果设置为文本时,不工作

using Firebase.Firestore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Json;
using UnityEngine;

public class MenuManager : MonoBehaviour
{
    private Usuario usuario;
    private Rank rank;
    private CollectionReference usuarioCollection;
    private CollectionReference rankCollection;

    public GameObject rankNomeLabel;

    public bool infoCarregadas;

    public GameObject botaoInfo;
    
    void Start()
    {
        this.rank = new Rank();
        this.botaoInfo.GetComponent<UnityEngine.UI.Button>().onClick.AddListener(() => this.CarregaInfos());
        //this.infoCarregadas = false;
    }
    
    void Update()
    {
        /*if (db != null && infoCarregadas == false)
        {
            this.CarregaInfos();
        } else
        {
            if (infoCarregadas == false)
            {
                db = FirebaseAuthenticator.instance.fsDB;
            }
            
        }*/
    }

    private void CarregaInfos()
    {
        try
        {
            FirebaseFirestore db = FirebaseAuthenticator.instance.fsDB;
            var usuarioJson = PlayerPrefs.GetString("usuario");
            this.usuario = usuarioJson != "" ? JsonUtility.FromJson<Usuario>(usuarioJson) : null;
            if (this.usuario != null && this.usuario.UID != null)
            {
                this.usuarioCollection = db.Collection("usuario");
                DocumentReference docRef = this.usuarioCollection.Document(usuario.UID);
                docRef.GetSnapshotAsync().ContinueWith(task =>
                {
                    DocumentSnapshot snapshot = task.Result;
                    if (snapshot.Exists)
                    {
                        Dictionary<string, object> usuario = snapshot.ToDictionary();

                        foreach (KeyValuePair<string, object> pair in usuario)
                        {
                            if (pair.Key == "rank")
                            {
                                this.rankCollection = db.Collection("rank");
                                DocumentReference docRef = this.rankCollection.Document(pair.Value.ToString());
                                docRef.GetSnapshotAsync().ContinueWith(task =>
                                {
                                    DocumentSnapshot snapshot = task.Result;
                                    if (snapshot.Exists)
                                    {
                                        Dictionary<string, object> rank = snapshot.ToDictionary();

                                        foreach (KeyValuePair<string, object> pair in rank)
                                        {
                                            if (pair.Key == "nome")
                                            {
                                                this.rankNomeLabel.GetComponent<UnityEngine.UI.Text>().text = pair.Value.ToString();
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Debug.Log("Erro ao carregar o rank: " + snapshot.Id);
                                    }
                                });
                            }
                        }
                    }
                    else
                    {
                        Debug.Log("Erro ao carregar o usuário: " + snapshot.Id);
                    }
                });
            }
            else
            {
                Debug.Log("Erro ao pegar usuário do PlayerPrefs");
            }
        }
        catch (Exception e)
        {
            Debug.LogError("Erro: " + e);
        }
    }
}

文本链接到变量(打印波纹管)

this.rankNomeLabel.GetComponent&lt;UnityEngine.UI.Text&gt;().text = pair.Value.ToString(); in this line, the reference is null

认为问题在于在异步方法中设置值,但我不知道如何解决它

有人知道发生了什么吗?

【问题讨论】:

    标签: c# firebase unity3d asynchronous google-cloud-firestore


    【解决方案1】:

    大部分 Unity API 只能在 Unity 主线程上使用(纯结构除外,因为它们只是数据容器,不会立即依赖或影响实际场景)。

    ContinueWith不保证在主线程中执行。

    因此 Firebase 提供了 Extension method ContinueWithOnMainThread

    将两个或至少内部的ContinueWith 替换为ContinueWithOnMainThreae 应该可以解决您的问题,或者至少可以更清楚地说明实际问题在哪里。


    而不是一遍又一遍地使用GetComponent,让你的生活更轻松,直接使用正确的类型

    using UnityEngine.UI;
    
    ...
    
    public Text rankNomeLabel;
    public Button botaoInfo;
    

    这还确保您只能拖入实际附加了相应组件的对象,并且在运行时不易出错,因为它已经确保它不是 null - 如果是(例如,如果对象是销毁)你也可以立即在 Inspector 中看到它

    【讨论】:

    • derHugo,它和 ContinueWithOnMainThread 一起工作,我会多研究 firebase 的 api 文档,非常感谢
    【解决方案2】:

    我通过检查更新方法中的布尔值解决了类似的问题。这并不花哨,但它确实有效。

    public class MyClass : MonoBehaviour
    {
        private bool updateUI = false;
    
        private async Task function() {
            updateUI = true;
        }
    
        private void Update() {
            if (updateUI) {
                // update your ui here
                ...
                updateUI = false;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-23
      • 1970-01-01
      • 2015-02-03
      • 1970-01-01
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多