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

Unity中从Firebase Storage批量下载图片并显示到不同对象的问题

问题:Firebase图片加载后仅显示在最后一个预制体面板

问题描述

通过Firestore获取服装数据并实例化预制体面板,字符串数据能正确显示,但所有Firebase Storage下载的图片仅显示在最后一个面板上,每个面板无法加载对应图片。

问题根源

核心原因是异步回调共享了类成员变量costImage:

  • 在循环调用SpawnWithImageTest时,每次都会将类成员costImage替换为当前新生成面板的RawImage引用。
  • 由于GetDownloadUrlAsync和后续的图片加载协程是异步操作,当这些异步任务完成时,costImage已经被覆盖为最后一次循环的面板引用,导致所有图片都被设置到最后一个面板上。

修复方案

将所有与当前面板绑定的控件变量改为局部变量,确保每个异步回调捕获的是当前面板的专属控件引用,避免被后续循环覆盖。

修正后的代码

修改后的SpawnWithImageTest方法

public void SpawnWithImageTest(string name, string franch, string size, int price, int waist, int chest)
{
    GameObject child = Instantiate(CostumePrefab);
    child.transform.SetParent(PanelHolder.transform, false);
    GameObject NameReq = child.transform.Find("Panel").transform.Find("CostName").gameObject;
    GameObject FranchiseReq = child.transform.Find("Panel").transform.Find("Franch").gameObject;
    GameObject SizeReq = child.transform.Find("Panel").transform.Find("Size").gameObject;
    GameObject PriceReq = child.transform.Find("Panel").transform.Find("Price").gameObject;
    GameObject CostImage = child.transform.Find("RawImage").gameObject;

    // 使用局部变量存储当前面板的控件引用,替代类成员变量
    TextMeshProUGUI reqName = NameReq.GetComponent<TextMeshProUGUI>();
    TextMeshProUGUI reqFranchise = FranchiseReq.GetComponent<TextMeshProUGUI>();
    TextMeshProUGUI reqSize = SizeReq.GetComponent<TextMeshProUGUI>();
    TextMeshProUGUI reqPrice = PriceReq.GetComponent<TextMeshProUGUI>();
    RawImage localCostImage = CostImage.GetComponent<RawImage>();

    reqName.text = name;
    reqFranchise.text = franch;
    reqSize.text = string.Format("{0} (W: {1} C: {2}) ", size, waist.ToString(), chest.ToString());
    reqPrice.text = price.ToString();

    string filename = string.Format("{0}.jpeg", ConvertNameToFileName(name, storedata));
    StorageReference imgcost = storageReference.Child(string.Format("uploads/{0}", filename));
    
    // 捕获当前面板的局部RawImage引用,确保异步任务对应正确的面板
    imgcost.GetDownloadUrlAsync().ContinueWithOnMainThread(task =>
    {
        if(!task.IsFaulted && !task.IsCanceled)
        {
            StartCoroutine(LoadImage(System.Convert.ToString(task.Result), localCostImage));
        }
        else
        {
            Debug.Log(task.Exception);
        }
    });
}

保留原LoadImage协程(无需修改)

IEnumerator LoadImage(string MediaUrl, RawImage img)
{
    UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
    Debug.Log(MediaUrl);
    yield return request.SendWebRequest();
    if (request.isNetworkError || request.isHttpError)
    {
        Debug.Log(request.error);
    }
    else
    {
        img.texture = ((DownloadHandlerTexture)request.downloadHandler).texture;
    }
}

额外说明

  • 若原类中的ReqName、ReqFranchise等成员变量没有其他业务场景使用,建议直接删除,避免后续代码误用。
  • 异步操作中捕获局部变量是Unity处理多实例异步加载的常用方案,能确保每个任务独立绑定对应的UI控件。

内容的提问来源于stack exchange,提问作者Hovanon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 22:55:16