Unity如何从服务器下载多张图片并实现画廊/幻灯片展示?
整合服务器图片下载与画廊展示方案
嘿,我来帮你把服务器多图下载和本地画廊的功能整合到一起!你的现有代码已经有了核心逻辑,只需要把下载的图片收集起来,再复用本地画廊的创建逻辑就行,下面是具体的步骤和完整代码:
问题分析
你当前的下载代码每次下载完成后直接覆盖了单个imageLoaded的纹理,所以只能显示一张图;而本地画廊代码已经实现了从纹理列表生成画廊的逻辑,我们只需要把服务器下载的纹理收集到这个列表里,再调用现成的创建方法就好。
整合步骤
- 复用现有
ImageLoader脚本:把服务器下载的逻辑整合到这个脚本里,这样可以直接用它的textures列表和CreateImages方法。 - 收集下载的纹理:修改下载逻辑,把每张下载完成的Texture2D添加到
textures列表中。 - 触发画廊创建:可以选择等所有图片下载完成后一次性创建,或者每下载完一张就创建一张(适合大数量图片,提升用户体验)。
- 替换过时的
WWW(可选但推荐):Unity已经弃用了WWW类,建议换成UnityWebRequestTexture来避免后续版本兼容问题。
完整整合代码
下面是修改后的ImageLoader脚本,整合了服务器下载和画廊创建的功能:
using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; // 用于UnityWebRequest public class ImageLoader : MonoBehaviour { [SerializeField] [Tooltip("The panel where new images will be added as children")] private RectTransform content; // 存储从服务器下载的图片ID列表(替换成你从myPhotos.txt加载的列表) private List<string> photoIds; private List<Texture2D> textures; private void Start() { Application.runInBackground = true; // 先加载图片ID列表,然后开始下载 LoadPhotoIdsFromFile(); StartCoroutine(DownloadImagesFromServer()); } // 从myPhotos.txt加载图片ID列表 private void LoadPhotoIdsFromFile() { photoIds = ES2.LoadList<string>("myPhotos.txt"); textures = new List<Texture2D>(); } // 从服务器批量下载图片 private IEnumerator DownloadImagesFromServer() { foreach (string photoId in photoIds) { // 发送获取上传文件的请求 var request = new GetUploadedRequest() .SetUploadId(photoId); // 等待请求响应 yield return request.Send((response) => { // 开始下载单张图片 StartCoroutine(DownloadSingleImage(response.Url)); }); } } // 下载单张图片并添加到纹理列表 private IEnumerator DownloadSingleImage(string downloadUrl) { // 推荐使用UnityWebRequestTexture替代WWW using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(downloadUrl)) { yield return uwr.SendWebRequest(); if (uwr.result != UnityWebRequest.Result.Success) { Debug.LogError($"下载图片失败: {uwr.error}"); } else { // 获取下载的纹理 Texture2D downloadedTexture = DownloadHandlerTexture.GetContent(uwr); // 添加到纹理列表 textures.Add(downloadedTexture); // 每下载一张就创建对应的画廊项(可选,也可以等全部下载完再调用CreateImages) AddSingleImageToGallery(downloadedTexture); } } // 如果你想等所有图片下载完再一次性创建画廊,取消下面的注释,注释上面的AddSingleImageToGallery //if (textures.Count == photoIds.Count) //{ // CreateImages(); //} } // 单张图片添加到画廊(实时加载) private void AddSingleImageToGallery(Texture2D texture) { GameObject imageObject = new GameObject($"ServerImage_{textures.Count}"); imageObject.transform.SetParent(content, false); // false保持原有缩放 Image imageComponent = imageObject.AddComponent<Image>(); imageComponent.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f); // 可以在这里设置图片的布局大小,比如适配HorizontalLayoutGroup imageObject.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 200); } // 批量创建画廊(等全部下载完成后调用) private void CreateImages() { foreach (var texture in textures) { GameObject imageObject = new GameObject($"ServerImage_{textures.IndexOf(texture)}"); imageObject.transform.SetParent(content, false); Image imageComponent = imageObject.AddComponent<Image>(); imageComponent.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f); imageObject.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 200); } } // 保留你原来的本地加载方法(如果需要同时支持本地和服务器) public IEnumerator LoadImagesFromLocal(string imagePath) { textures = new List<Texture2D>(); DirectoryInfo di = new DirectoryInfo(imagePath); var files = di.GetFiles("*.png"); foreach (var file in files) { Debug.Log(file.FullName); yield return LoadTextureAsync(file.FullName, AddLoadedTextureToCollection); } CreateImages(); } private void AddLoadedTextureToCollection(Texture2D texture) { textures.Add(texture); } private IEnumerator LoadTextureAsync(string originalFileName, System.Action<Texture2D> result) { string fileToLoad = GetCleanFileName(originalFileName); Debug.Log("Loading Image from path: " + fileToLoad); using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(fileToLoad)) { yield return uwr.SendWebRequest(); if (uwr.result != UnityWebRequest.Result.Success) { Debug.LogError(uwr.error); } else { Texture2D loadedTexture = DownloadHandlerTexture.GetContent(uwr); result(loadedTexture); } } } private static string GetCleanFileName(string originalFileName) { string fileToLoad = originalFileName.Replace('\\', '/'); if (!fileToLoad.StartsWith("http")) { fileToLoad = $"file://{fileToLoad}"; } return fileToLoad; } }
关键修改点说明
- 替换
WWW为UnityWebRequestTexture:这是Unity官方推荐的新API,更稳定且支持更多特性。 - 纹理收集逻辑:把每张下载完成的Texture2D添加到
textures列表,和本地加载的逻辑保持一致。 - 两种画廊创建方式:
- 实时创建:每下载完一张就生成对应的画廊项,适合用户需要快速看到内容的场景。
- 批量创建:等所有图片下载完成后一次性生成,适合需要统一布局的场景。
- 布局适配:添加
imageObject.GetComponent<RectTransform>().sizeDelta = new Vector2(200, 200);来确保图片大小和你的ScrollView、HorizontalLayoutGroup适配。
注意事项
- 确保你的
GetUploadedRequest类能正确返回图片的下载URL,调试时可以打印response.Url确认是否有效。 - 给
content面板正确添加HorizontalLayoutGroup、ContentSizeFitter组件,确保画廊能正确滚动。 - 处理网络异常:代码里已经添加了错误日志,你可以根据需求添加重试逻辑或错误提示UI。
内容的提问来源于stack exchange,提问作者Angelsm
相关产品推荐
相关产品推荐

