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

Unity场景中图片每次加载顺序不一致的问题求助

解决Unity异步下载图片显示顺序混乱的问题

我来帮你搞定这个图片顺序乱跳的问题~

问题原因

你的代码里每个图片都是通过异步网络请求下载的,而网络请求的完成时间是不确定的——比如第0张图片可能因为网络延迟最后下载完成,它就会被最后实例化出来,导致显示顺序和你期望的photolist顺序不一致。虽然你给每个图片命名加了index,但实例化的顺序完全由请求返回的速度决定,自然每次进入场景顺序都不一样。

解决方案:固定占位,异步填充

最直观友好的解决方式是先按固定顺序创建所有图片的占位容器,等图片下载完成后再把纹理赋值给对应位置的占位。这样不管下载速度快慢,图片的位置从一开始就是固定的,下载完成后只是填充内容而已。

修改后的代码如下:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ImageDownloader : MonoBehaviour
{
    public GameObject contentRef; 
    public RawImage imgPrefab;
    // 存储按顺序创建的图片占位,用于后续赋值纹理
    private List<RawImage> _imagePlaceholders = new List<RawImage>(); 

    void Start() 
    { 
        DownloadtheFiles(); 
    } 

    public void DownloadtheFiles() 
    { 
        List<string> photolist = ES2.LoadList<string>("myPhotos.txt"); 
        
        // 第一步:先按photolist的顺序创建所有图片占位
        for (int i = 0; i < photolist.Count; i++)
        {
            RawImage placeholder = Instantiate(imgPrefab, contentRef.transform);
            placeholder.name = "Image-" + i;
            _imagePlaceholders.Add(placeholder);
            // 可选:给占位设置一张加载中的默认图,提升用户体验
            // placeholder.texture = Resources.Load<Texture2D>("LoadingPlaceholder");
        }

        // 第二步:开始异步下载图片
        for (int i = 0; i < photolist.Count; i++) 
        { 
            // 捕获当前循环的index,避免闭包陷阱
            int index = i; 
            new GetUploadedRequest() 
                .SetUploadId(photolist[index]) 
                .Send((response) => { 
                    StartCoroutine(DownloadImages(response.Url, index)); 
                }); 
        } 
    } 

    public IEnumerator DownloadImages(string downloadUrl, int index) 
    { 
        var www = new WWW(downloadUrl); 
        yield return www; 

        // 加载下载到的图片纹理
        Texture2D tex = new Texture2D(4, 4); 
        www.LoadImageIntoTexture(tex); 

        // 直接给对应index的占位图片赋值纹理
        _imagePlaceholders[index].texture = tex; 
    }
}

另一种方案:全部下载完成后再按顺序实例化

如果你的需求是等所有图片都下载完成后再一次性显示,可以用字典存储下载好的纹理,等全部完成后按index排序再实例化:

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class ImageDownloader : MonoBehaviour
{
    public GameObject contentRef; 
    public RawImage imgPrefab;
    // 存储下载完成的纹理,key是index
    private Dictionary<int, Texture2D> _loadedTextures = new Dictionary<int, Texture2D>();
    private int _totalImageCount;

    void Start() 
    { 
        DownloadtheFiles(); 
    } 

    public void DownloadtheFiles() 
    { 
        List<string> photolist = ES2.LoadList<string>("myPhotos.txt"); 
        _totalImageCount = photolist.Count;
        
        for (int i = 0; i < photolist.Count; i++) 
        { 
            int index = i; 
            new GetUploadedRequest() 
                .SetUploadId(photolist[index]) 
                .Send((response) => { 
                    StartCoroutine(DownloadImages(response.Url, index)); 
                }); 
        } 
    } 

    public IEnumerator DownloadImages(string downloadUrl, int index) 
    { 
        var www = new WWW(downloadUrl); 
        yield return www; 

        Texture2D tex = new Texture2D(4, 4); 
        www.LoadImageIntoTexture(tex); 
        _loadedTextures[index] = tex;

        // 检查是否所有图片都已下载完成
        if (_loadedTextures.Count == _totalImageCount)
        {
            // 按index排序后依次实例化
            var sortedTextures = _loadedTextures.OrderBy(kv => kv.Key);
            foreach (var texturePair in sortedTextures)
            {
                RawImage newImg = Instantiate(imgPrefab, contentRef.transform);
                newImg.name = "Image-" + texturePair.Key;
                newImg.texture = texturePair.Value;
            }
        }
    }
}

补充说明

如果你的contentRef使用了VerticalLayoutGroup或HorizontalLayoutGroup这类布局组件,第一种方案的占位会自动按创建顺序排列,完全符合你的需求;第二种方案适合需要避免加载过程中图片逐个弹出的场景。

附上你提供的两次场景截图:
第一次进入场景的图片顺序:
第一次进入场景的图片顺序
第二次进入场景的图片顺序:
第二次进入场景的图片顺序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:07:49