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

Unity从StreamingAssets加载CSV失败:ID列找不到问题求助

解决Unity从StreamingAssets加载CSV时找不到"ID"列的问题

问题根源

从StreamingAssets通过UnityWebRequest加载CSV时,导致表头解析错误的常见原因:

  • 换行符跨平台不一致,原正则无法正确分割行
  • CSV文件带UTF-8 BOM头,导致表头字段被额外字符污染
  • 未正确使用协程等待UnityWebRequest下载完成,拿到不完整/空文本

修复步骤

1. 修正CSVReader的Read方法(处理BOM和通用换行)

修改接收字符串的Read方法,添加BOM移除逻辑,替换更通用的换行分割正则:

using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class CSVReader
{
    static string SPLIT_RE = @",(?=(?:[^"]*"[^"]*")*(?![^"]*"))";
    static char[] TRIM_CHARS = { '"' };

    // 保留原Resources加载方法(可选)
    public static List<Dictionary<string, object>> Read(string file)
    {
        TextAsset data = Resources.Load(file) as TextAsset;
        return Read(data.text); // 复用字符串版核心逻辑
    }

    // 处理字符串的核心方法
    public static List<Dictionary<string, object>> Read(string data)
    {
        var list = new List<Dictionary<string, object>>();
        
        // 移除UTF-8 BOM头(部分CSV保存时会自动添加)
        if (!string.IsNullOrEmpty(data) && data[0] == '\ufeff')
        {
            data = data.Substring(1);
        }
        
        // 匹配所有平台换行符:Windows(\r\n)、Linux(\n)、Mac(\r)
        var lines = Regex.Split(data, @"\r?\n|\r");

        if (lines.Length <= 1) return list;

        var header = Regex.Split(lines[0], SPLIT_RE);
        // 清理表头的空白和多余引号
        for (int j = 0; j < header.Length; j++)
        {
            header[j] = header[j].Trim().Trim(TRIM_CHARS);
        }
        
        for (var i = 1; i < lines.Length; i++)
        {
            var line = lines[i].Trim();
            if (string.IsNullOrEmpty(line)) continue;

            var values = Regex.Split(line, SPLIT_RE);
            if (values.Length == 0) continue;

            var entry = new Dictionary<string, object>();
            for (var j = 0; j < header.Length && j < values.Length; j++)
            {
                string value = values[j];
                value = value.TrimStart(TRIM_CHARS).TrimEnd(TRIM_CHARS).Replace("\\", "");
                object finalvalue = value;
                int n;
                float f;
                if (int.TryParse(value, out n))
                {
                    finalvalue = n;
                }
                else if (float.TryParse(value, out f))
                {
                    finalvalue = f;
                }
                entry[header[j]] = finalvalue;
            }
            list.Add(entry);
        }
        return list;
    }
}

2. 修正LoadExcel的加载逻辑(使用协程+编码设置)

确保加载方法是协程,等待下载完成,并指定UTF-8编码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class LoadExcel : MonoBehaviour
{
    void Start()
    {
        // 必须用协程启动异步加载流程
        StartCoroutine(LoadItemData());
    }

    IEnumerator LoadItemData()
    {
        string path = Path.Combine(Application.streamingAssetsPath, "MyExcel.csv");
        UnityWebRequest uwr = UnityWebRequest.Get(path);
        
        // 强制指定UTF-8编码,避免乱码问题
        uwr.downloadHandler = new DownloadHandlerBuffer();
        uwr.downloadHandler.textEncoding = System.Text.Encoding.UTF8;
        
        yield return uwr.SendWebRequest();

        // 错误处理,快速定位加载失败原因
        if (uwr.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError("CSV加载失败: " + uwr.error);
            yield break;
        }

        List<Dictionary<string, object>> data = CSVReader.Read(uwr.downloadHandler.text);
        
        // 可选:打印表头验证是否包含ID字段
        if (data.Count > 0)
        {
            Debug.Log("表头字段列表:");
            foreach (var key in data[0].Keys)
            {
                Debug.Log("- " + key);
            }
        }
    }
}

关键说明

  • BOM处理:Excel导出的CSV常带UTF-8 BOM,直接读取会导致表头第一个字段前附加\ufeff(如\ufeffID),自然无法匹配"ID"字段。
  • 换行正则:原代码的换行正则写法存在显示异常,替换为\r?\n|\r可兼容所有平台的换行格式。
  • 协程必要性:UnityWebRequest是异步操作,必须用yield return等待下载完成,否则会读取到空或不完整的文本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 12:54:54