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

Unity如何正确加载图片到类数组并解决索引越界异常

问题根因

两个报错和异常现象来自三处明确的代码逻辑错误:

  • 数组越界异常:所有遍历数组的for循环都使用了i <= 数组长度的判断条件,C#数组索引从0开始计数,最大合法索引值为数组长度 - 1,当循环变量等于数组长度时访问数组,必然触发IndexOutOfRangeException
  • 非图片字段全为空:图片下载协程DownloadImage每次拿到单张图片后,都会重新实例化整个DataClassArray数组及内部的所有CollectionDataClass元素,之前在GenerateCollectionData里填充好的name/id/thumbnail字段会被全部清空覆盖
  • 仅加载出一张图片:DownloadImage拿到单张图片后,会把这张图片循环赋值给所有集合项,最终所有项只会保留最后一次下载完成的图片;同时调用协程时传入的count参数没有实际定位作用,没有把图片和对应的集合项做绑定。
修复方案
  1. 所有数组遍历循环的判断条件从i <= 数组.Length修改为i < 数组.Length,解决越界问题
  2. 移除DownloadImage协程里全量重建数组、遍历所有元素赋值的逻辑,下载完成后直接给对应索引位置的已有元素赋值即可
  3. 调用DownloadImage时传入当前元素对应的外层、内层索引,准确定位要赋值图片的集合项,避免全量覆盖。
修正后代码
[System.Serializable]
public class CollectionDataClass
{
    public string name;
    public string id;
    public string thumbnail;
    public Texture2D collectionImage;
}

[System.Serializable]
public class DataClass
{
    [SerializeField] public CollectionDataClass[] collectionDataClass;
}

[SerializeField] private DataClass[] DataClassArray;

public IEnumerator BookCatogary(string reqParameter)
{
    BookCatogaryBodyClass BookCatogryClass = new BookCatogaryBodyClass(reqParameter);
    string json = JsonConvert.SerializeObject(BookCatogryClass);
    Debug.Log("==========================>" + json);

    var req = new UnityWebRequest(bookCategaryAPI, "POST");
    byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json);

    req.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
    req.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
    req.SetRequestHeader("Content-Type", "application/json");

    yield return req.SendWebRequest();

    if (req.isNetworkError)
    {
        Debug.Log("Error While Sending: " + req.error);
    }
    else
    {
        Debug.Log("Received: " + req.downloadHandler.text);
        string temp = req.downloadHandler.text;
        bookCatogaryObject = JsonConvert.DeserializeObject<BookCatogaryReceivedDataClass>(temp);
        catogaryCount = bookCatogaryObject.Data.Rows.Count;

        GetCatogariesName(catogaryCount);
        GenerateCollectionData();
    }
}


public void GenerateCollectionData()
{
    int rowCount = bookCatogaryObject.Data.Rows.Count;
    DataClassArray = new DataClass[rowCount];

    // 修复循环条件:<= 改为 <
    for (int i = 0; i < rowCount; i++)
    {
        DataClassArray[i] = new DataClass();
        int itemCount = bookCatogaryObject.Data.Rows[i].String.Count;
        DataClassArray[i].collectionDataClass = new CollectionDataClass[itemCount];

        for (int m = 0; m < itemCount; m++)
        {
            DataClassArray[i].collectionDataClass[m] = new CollectionDataClass();
            DataClassArray[i].collectionDataClass[m].name = bookCatogaryObject.Data.Rows[i].String[m].CollectionTitle;
            DataClassArray[i].collectionDataClass[m].id = bookCatogaryObject.Data.Rows[i].String[m].Id;
            DataClassArray[i].collectionDataClass[m].thumbnail = bookCatogaryObject.Data.Rows[i].String[m].CollectionThumbnail;
            // 传入当前元素的索引,准确定位赋值位置
            StartCoroutine(DownloadImage(DataClassArray[i].collectionDataClass[m].thumbnail, i, m));
        }
    }
}

// 修改参数,接收外层i、内层m索引
IEnumerator DownloadImage(string mediaUrl, int rowIndex, int itemIndex)
{
    UnityWebRequest request = UnityWebRequestTexture.GetTexture(mediaUrl);
    yield return request.SendWebRequest();
    if (request.isNetworkError || request.isHttpError)
    {
        Debug.Log(request.error);
    }
    else
    {
        // 直接给对应索引的元素赋值,不重建整个数组
        Texture2D loadedTex = ((DownloadHandlerTexture)request.downloadHandler).texture;
        DataClassArray[rowIndex].collectionDataClass[itemIndex].collectionImage = loadedTex;
    }
}

注意:如果使用的是Unity 2020及以上版本,isNetworkError、isHttpError已被标记为过时,可替换为result != UnityWebRequest.Result.Success做请求结果判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:48:51