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

Unity如何从服务器下载多张图片并实现画廊/幻灯片展示?

整合服务器图片下载与画廊展示方案

嘿,我来帮你把服务器多图下载和本地画廊的功能整合到一起!你的现有代码已经有了核心逻辑,只需要把下载的图片收集起来,再复用本地画廊的创建逻辑就行,下面是具体的步骤和完整代码:

问题分析

你当前的下载代码每次下载完成后直接覆盖了单个imageLoaded的纹理,所以只能显示一张图;而本地画廊代码已经实现了从纹理列表生成画廊的逻辑,我们只需要把服务器下载的纹理收集到这个列表里,再调用现成的创建方法就好。

整合步骤

  1. 复用现有ImageLoader脚本:把服务器下载的逻辑整合到这个脚本里,这样可以直接用它的textures列表和CreateImages方法。
  2. 收集下载的纹理:修改下载逻辑,把每张下载完成的Texture2D添加到textures列表中。
  3. 触发画廊创建:可以选择等所有图片下载完成后一次性创建,或者每下载完一张就创建一张(适合大数量图片,提升用户体验)。
  4. 替换过时的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适配。

注意事项

  1. 确保你的GetUploadedRequest类能正确返回图片的下载URL,调试时可以打印response.Url确认是否有效。
  2. 给content面板正确添加HorizontalLayoutGroup、ContentSizeFitter组件,确保画廊能正确滚动。
  3. 处理网络异常:代码里已经添加了错误日志,你可以根据需求添加重试逻辑或错误提示UI。

内容的提问来源于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 08:57:46