182 lines
6.3 KiB
C#
182 lines
6.3 KiB
C#
using SK.Framework;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// Excel数据解析器
|
|
/// </summary>
|
|
public class CSVReader : MonoBehaviour
|
|
{
|
|
public DialogueData ParseDialogueData(string path)
|
|
{
|
|
//检查文件是否存在
|
|
if (!File.Exists(path)) return null;
|
|
|
|
//创建对话数据对象
|
|
DialogueData dialogueData = new DialogueData();
|
|
DialogueEntry currentEntry = null;
|
|
bool isProcessEvent = false;
|
|
DialogueEntry eventEntry = null;
|
|
|
|
//读取文件内容
|
|
string[] lines = File.ReadAllLines(path);
|
|
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
string line = lines[i];
|
|
if (string.IsNullOrWhiteSpace(line)) continue;
|
|
|
|
//分割行数据
|
|
string[] parts = line.Split('|');
|
|
|
|
//清理每个部分
|
|
for (int j = 0; j < parts.Length; j++)
|
|
{
|
|
parts[j] = parts[j].Trim();
|
|
}
|
|
|
|
if (parts.Length < 2) continue;
|
|
|
|
//解析角色行
|
|
if (parts[0].Equals("角色"))
|
|
{
|
|
//如果正在处理事件,先保存事件条目
|
|
if (isProcessEvent && eventEntry != null)
|
|
{
|
|
dialogueData.entries.Add(eventEntry);
|
|
isProcessEvent = false;
|
|
eventEntry = null;
|
|
}
|
|
|
|
//保存上一个对话条目
|
|
if (currentEntry != null && (currentEntry.dialogues.Count > 0 || currentEntry.hasEvent))
|
|
dialogueData.entries.Add(currentEntry);
|
|
|
|
//创建新的对话条目
|
|
currentEntry = new DialogueEntry
|
|
{
|
|
role = parts[1],
|
|
dialogues = new List<string>(),
|
|
hasEvent = false,
|
|
eventName = "",
|
|
eventRole = "",
|
|
eventChoices = new List<string>(),
|
|
nextEntryIndex = -1
|
|
};
|
|
}
|
|
//解析对话行
|
|
else if (parts[0].Equals("对话") && currentEntry != null)
|
|
{
|
|
for (int j = 1; j < parts.Length; j++)
|
|
{
|
|
if (!string.IsNullOrEmpty(parts[j]) && !parts[j].Equals("xxxxx"))
|
|
{
|
|
currentEntry.dialogues.Add(parts[j]);
|
|
}
|
|
}
|
|
}
|
|
//解析事件行
|
|
else if (parts[0].Equals("事件") && currentEntry != null)
|
|
{
|
|
if (currentEntry != null)
|
|
{
|
|
currentEntry.hasEvent = true;
|
|
currentEntry.eventName = "交互事件";
|
|
}
|
|
|
|
//创建独立的事件条目
|
|
eventEntry = new DialogueEntry
|
|
{
|
|
role = "系统事件",
|
|
dialogues = new List<string>(),
|
|
hasEvent = true,
|
|
eventName = "玩家选择事件",
|
|
eventRole = "",
|
|
eventChoices = new List<string>(),
|
|
nextEntryIndex = -1
|
|
};
|
|
isProcessEvent = true;
|
|
}
|
|
//解析事件角色行
|
|
else if (parts[0].Equals("事件角色") && eventEntry != null && isProcessEvent)
|
|
{
|
|
eventEntry.eventRole = parts[1];
|
|
}
|
|
//解析事件选项行
|
|
else if (parts[0].Equals("事件选项") && isProcessEvent && eventEntry != null)
|
|
{
|
|
for (int j = 1; j < parts.Length; j++)
|
|
{
|
|
if (!string.IsNullOrEmpty(parts[j]) && !parts[j].Equals("xxxxx"))
|
|
eventEntry.eventChoices.Add(parts[j]);
|
|
}
|
|
|
|
//检查后续行是否也是选项
|
|
int nextLineIndex = i + 1;
|
|
while (nextLineIndex < line.Length)
|
|
{
|
|
string nextLine = lines[nextLineIndex].Trim();
|
|
if (string.IsNullOrEmpty(nextLine)) break;
|
|
string[] nextparts = nextLine.Split('|');
|
|
if (nextparts.Length > 0 && string.IsNullOrEmpty(nextparts[0].Trim()))
|
|
{
|
|
//选项的延续行
|
|
for (int j = 0; j < nextparts.Length; j++)
|
|
{
|
|
string option = parts[j].Trim();
|
|
if (!string.IsNullOrEmpty(option))
|
|
eventEntry.eventChoices.Add(option);
|
|
}
|
|
i = nextLineIndex; //跳过已处理的行
|
|
nextLineIndex++;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//处理空行中的对话内容(对话延续)
|
|
else if (parts.Length > 0 && string.IsNullOrEmpty(parts[0]) && currentEntry != null)
|
|
{
|
|
for (int j = 0; j < parts.Length; j++)
|
|
{
|
|
if (!string.IsNullOrEmpty(parts[j]))
|
|
currentEntry.dialogues.Add(parts[j]);
|
|
}
|
|
}
|
|
}
|
|
//保留最后一个条目
|
|
if (currentEntry != null && (currentEntry.dialogues.Count > 0 || currentEntry.hasEvent))
|
|
{
|
|
dialogueData.entries.Add(currentEntry);
|
|
}
|
|
|
|
//保留最后一个事件条目
|
|
if (isProcessEvent && eventEntry != null)
|
|
{
|
|
dialogueData.entries.Add((eventEntry));
|
|
}
|
|
//BuildEventJumpTable(dialogueData);
|
|
return dialogueData;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 创建事件跳过
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void BuildEventJumpTable(DialogueData data)
|
|
{
|
|
for (int i = 0; i < data.entries.Count; i++)
|
|
{
|
|
if (data.entries[i].hasEvent && !string.IsNullOrEmpty(data.entries[i].eventName))
|
|
{
|
|
string eventKey = $"{data.entries[i].eventRole}_{data.entries[i].eventName}";
|
|
if (!data.eventJumpTable.ContainsKey(eventKey))
|
|
data.eventJumpTable.Add(eventKey, i);
|
|
}
|
|
}
|
|
}
|
|
} |