如何快速显示服务器下载的多张图片?RawImage实例化失败排查
解决Unity下载多张图片后排序显示的问题
我帮你梳理下代码里的几个关键问题,这些问题导致你的图片无法正常排序和显示:
错误1:每次下载都新建Texture列表,根本存不住所有图片
你在DownloadImages里每次都new List<Texture2D>(),这意味着每张图片下载完成后都只会存在自己的临时列表里,所有下载完成后根本没有一个统一的列表来存储所有Texture,自然没法统一排序。错误2:误用
tex.Count,Texture2D没有这个属性tex是单个Texture2D对象,它没有Count属性,你这里想遍历的应该是存储所有Texture的列表,但逻辑完全错了。错误3:下载一张就实例化一张,违背了“所有下载完成后排序再实例化”的需求
你现在的逻辑是下载完一张就立刻实例化,而不是等所有图片都下载完成、排序后再统一创建RawImage,这和你原本的需求不符。错误4:Texture2D默认没有名称,排序逻辑形同虚设
你想按mtex.name排序,但默认创建的Texture2D的name是空字符串,就算排序也不会有任何效果,必须给每个Texture设置对应的名称(比如从你的photolist里的上传ID或者文件名来设置)。额外问题:WWW已经被Unity废弃,建议用UnityWebRequest
WWW在Unity 2017之后就被标记为过时了,官方推荐使用UnityWebRequestTexture来下载图片,更稳定高效。
修正后的完整代码
using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; using System.Collections; using System.Collections.Generic; using System.Linq; using System; public class ImageDownloader : MonoBehaviour { public GameObject contentRef; public RawImage imgPrefab; // 全局列表,用来存储所有下载完成的Texture和对应名称 private List<TextureWithName> _allDownloadedTextures = new List<TextureWithName>(); // 自定义类,关联Texture和它的名称(方便排序) private class TextureWithName { public string DisplayName { get; set; } public Texture2D Texture { get; set; } } void Start() { StartCoroutine(DownloadAllImages()); } public IEnumerator DownloadAllImages() { List<string> photoUploadIds = ES2.LoadList<string>("myPhotos.txt"); foreach (string uploadId in photoUploadIds) { bool currentRequestDone = false; string currentId = uploadId; // 捕获当前循环变量,避免回调引用问题 new GetUploadedRequest() .SetUploadId(currentId) .Send((response) => { StartCoroutine(DownloadSingleImage(response.Url, currentId, (isSuccess, texture) => { if (isSuccess && texture != null) { // 将下载好的图片存入全局列表 _allDownloadedTextures.Add(new TextureWithName { DisplayName = currentId, // 这里用上传ID当名称,可替换为实际文件名 Texture = texture }); } currentRequestDone = isSuccess; })); }); // 等待当前图片下载完成再继续下一个 while (!currentRequestDone) yield return null; } // 所有图片下载完成后,按名称排序 var sortedTextures = _allDownloadedTextures.OrderBy(item => item.DisplayName).ToList(); // 统一实例化并显示所有图片 foreach (var textureItem in sortedTextures) { RawImage newImage = Instantiate(imgPrefab, contentRef.transform); newImage.name = $"Image-{textureItem.DisplayName}"; newImage.texture = textureItem.Texture; } } public IEnumerator DownloadSingleImage(string downloadUrl, string textureName, Action<bool, Texture2D> onComplete) { // 使用Unity官方推荐的UnityWebRequest替代过时的WWW using (UnityWebRequest webRequest = UnityWebRequestTexture.GetTexture(downloadUrl)) { yield return webRequest.SendWebRequest(); if (webRequest.result != UnityWebRequest.Result.Success) { Debug.LogError($"图片下载失败: {webRequest.error}"); onComplete?.Invoke(false, null); } else { Texture2D downloadedTexture = DownloadHandlerTexture.GetContent(webRequest); // 也可以直接给Texture赋值name,这样后续直接用texture.name排序也行 // downloadedTexture.name = textureName; onComplete?.Invoke(true, downloadedTexture); } } } }
关键改动说明
- 全局列表存储所有图片:用
_allDownloadedTextures统一管理所有下载完成的图片,确保所有图片都被收集后再进行排序。 - 调整执行流程:把实例化RawImage的逻辑移到所有图片下载完成后,先排序再批量创建,完全符合你“先下载、再排序、最后显示”的需求。
- 替换过时API:用
UnityWebRequestTexture替代WWW,提升下载稳定性和兼容性。 - 修复变量捕获问题:在foreach循环中用
currentId捕获当前的上传ID,避免回调函数引用到循环变量的最新值导致的错误。 - 有效排序逻辑:通过
TextureWithName类关联图片名称和Texture,确保排序时能正确按名称排序(你可以把DisplayName换成接口返回的实际文件名,效果更准确)。 - 错误处理:新增下载失败的日志输出,方便调试问题。
内容的提问来源于stack exchange,提问作者Angelsm
相关产品推荐
相关产品推荐

