IEnumerator LoadMachineConfig(string fileName) { string path = Path.Combine(Application.streamingAssetsPath, fileName); string csvData; try { #if UNITY_ANDROID && !UNITY_EDITOR using (var www = UnityEngine.Networking.UnityWebRequest.Get(path)) { yield return www.SendWebRequest(); if (www.isNetworkError || www.isHttpError) { Debug.LogError("Error loading CSV file: " + www.error); yield break; } csvData = www.downloadHandler.text; } #else csvData = File.ReadAllText(path); #endif var machineGroups = new Dictionary<int, GachaMachineConfig>(); string[] lines = csvData.Split(new[] { "\r\n", "\n" }, System.StringSplitOptions.RemoveEmptyEntries); //Debug.Log($"CSV 文件头 20 个字符: {csvData.Substring(0, Mathf.Min(20, csvData.Length))}"); for (int i = 1; i < lines.Length; i++) { string[] fields = SplitCSVLine(lines[i]); if (fields.Length < 8) continue; int machineID = int.Parse(fields[0]); if (!machineGroups.TryGetValue(machineID, out var config)) { config = new GachaMachineConfig { machineID = machineID, isActive = fields[1] == "0", // 0表示启用 machineName = fields[2], machineColor = ParseColor(fields[3]) }; machineGroups[machineID] = config; keyOrder.Add(machineID); } config.tiers.Add(new Tier { tierName = fields[4], tierID = int.Parse(fields[5]), probability = float.Parse(fields[6]), textColor = ParseColor(fields[7]) }); }
时间: 2025-07-05 21:45:52 浏览: 13
<think>好的,用户想在Unity中使用C#通过IEnumerator加载并解析CSV文件到字典中。我需要先理解IEnumerator的用途,它通常用于协程,处理需要等待的操作,比如文件读取或网络请求。用户可能希望不阻塞主线程,所以用协程是正确的选择。
接下来,处理CSV文件。Unity中读取文件可以用Resources.Load或者System.IO.File。如果文件放在Resources文件夹下,可以用前者,否则用后者。但要注意路径问题。用户可能需要处理较大的文件,所以流式读取可能更高效,比如使用StreamReader逐行读取。
解析CSV时,需要考虑逗号分隔的值,但如果有字段包含逗号或换行符,可能需要更复杂的解析逻辑。不过对于简单的配置文件,可能基础的分割就足够。每行的第一个字段作为字典的键,剩下的作为值。可能需要处理不同数据类型的转换,比如整数、浮点数,但用户的问题中没有提到具体类型,所以先保持为字符串。
异常处理也很重要,比如文件不存在、格式错误等,应该加入try-catch块,并在协程中返回状态,比如成功或失败。用户可能需要知道加载是否完成,所以用回调或者事件来通知完成。
然后,示例代码的结构应该是这样的:一个协程方法,使用WWW或UnityWebRequest加载文件,或者直接读取。然后逐行解析,跳过空行和注释行(如果有的话),分割每一行,将数据存入字典。
可能还需要处理表头,但用户提到的是配置文件,可能没有表头,所以直接按行处理。例如,每行格式为key,value1,value2,...,那么将key作为字典的键,值部分作为字符串数组存储。
最后,生成相关问题,需要考虑用户可能遇到的后续问题,比如异步加载、处理大文件、特殊字符、数据验证等。确保问题覆盖用户可能的进一步需求。</think>在Unity中实现CSV文件加载解析功能时,建议采用协程配合字典存储数据。以下是分步实现示例:
```csharp
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class CSVLoader : MonoBehaviour
{
// 协程方法:加载并解析CSV文件
public IEnumerator LoadCSVFile(string filePath)
{
Dictionary<string, string[]> configData = new Dictionary<string, string[]>();
bool isSuccess = false;
try {
using (StreamReader reader = new StreamReader(filePath))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
// 跳过空行和注释行
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
continue;
// 分割CSV行数据
string[] parts = line.Split(',');
if (parts.Length < 2)
{
Debug.LogWarning($"Invalid line format: {line}");
continue;
}
// 提取键值对
string key = parts[0].Trim();
string[] values = new string[parts.Length - 1];
System.Array.Copy(parts, 1, values, 0, parts.Length - 1);
configData.Add(key, values);
yield return null; // 每行处理间隔一帧
}
isSuccess = true;
}
}
catch (System.Exception e) {
Debug.LogError($"CSV加载失败: {e.Message}");
}
yield return new LoadResult(isSuccess, configData);
}
// 封装加载结果
public class LoadResult
{
public bool Success { get; }
public Dictionary<string, string[]> Data { get; }
public LoadResult(bool success, Dictionary<string, string[]> data)
{
Success = success;
Data = data;
}
}
}
```
使用示例:
```csharp
StartCoroutine(LoadCSVFile(Path.Combine(Application.streamingAssetsPath, "config.csv"), (result) => {
if (result.Success) {
foreach (var item in result.Data) {
Debug.Log($"Key:{item.Key}, Values:{string.Join(",", item.Value)}");
}
}
}));
```
关键实现要点:
1. 采用流式读取避免内存压力
2. 使用`yield return null`保持帧率稳定
3. 添加数据有效性校验
4. 支持注释行(以#开头)
5. 异常捕获机制
6. 使用专门的结果类封装状态
特殊字符处理可通过正则表达式加强:
```csharp
string[] parts = System.Text.RegularExpressions.Regex.Split(line,
"(?:^|,)(\"(?:[^\"]+|\"\")*\"|[^,]*)");
```
阅读全文
相关推荐



















