CSV解析器
class_name CSVTool extends Object
# 使用 static 构造静态函数,可无需加载脚本,直接以 类名.函数名(CSVTool.load) 的方式调用方法
static func load(csv_path: String):
assert(FileAccess.file_exists(csv_path), "文件不存在!") # 使用 assert 进行断言,如果传回条件为false会直接打断后续操作。file_exists 方法如果获取不到文件,返回false。
var file: FileAccess = FileAccess.open(csv_path, FileAccess.READ) # 打开 CSV 文件进行读取操作
var head: PackedStringArray = file.get_csv_line(",") # 读取第一行作为表头(标题行)
var type: PackedStringArray = file.get_csv_line(",") # 读取第二行作为数据类型定义行
file.get_csv_line(",") # 此代码仅用于跳过注释行
var items = [] # 用于存储所有的数据
while not file.eof_reached(): # 循环读取整个文件,如果光标已经读到了文件末尾,eof_reached 会返回 true。
var data: PackedStringArray = file.get_csv_line(",") # 从第三行开始,for 循环读取当前行数据。
var row: Dictionary = {} # 存储当前行数据
for i in data.size(): # 遍历表头的每一个列标题
var title = head[i] # 获取列标题,作为字典的键名。
var value = data[i] # 获取单元格,作为字典的键值。
match type[i]: # match 作用相当于 type[i] == int/flo……。即,寻找第i个元素,并确认其是否为对应类型代码。行(第i个)列(是否为对应类型列)都确定就可以找到值了。
"int": row[title] = value.to_int()
"flo": row[title] = value.to_float()
"boo": row[title] = bool(value.to_int())
"tex":
row[title] = (ResourceLoader.load(value) as Texture) if ResourceLoader.exists(value) else null
"ori":
var ori = []
# 目前功能只具备初步效果,分析格式字符串中是否有player关键字,存在则获取对应属性
for item in value.strip_edges().split("|"):
ori.append(Player.get(item) if item.begins_with("player") else item)
# 查找 title 为 "dialog" 的字段并进行 % ori 操作
for key in row.keys(): if key == "dialog": row[key] = row[key] % ori
"arr":
var elements = []
for element in value.strip_edges().split("|"):
var temporary = []
# 数据类型转化
for item in element.split(","):
temporary.append(item.to_float() if item.is_valid_float() else item.to_int() if item.is_valid_int() else item)
if title == "checks": temporary.resize(3) # 标题为 checks 表示这是一个用于检定选项的数组,使用 resize 方法调整数组元素个数,避免调用时因数量不足而报错
elements.append(temporary)
row[title] = elements
_: row[title] = value
if not row.is_empty(): items.append(row) # 将所有数据添加到 items 数组中, 方法 is_empty 会为空字典返回true。
#for row in items:
#for title in row.keys():
#if type[head.find(title)] == "plo":
#for placeholder_list in oris:
#for i in range(placeholder_list.size()):
#if placeholder_list[i].begins_with("player"): placeholder_list[i] = Player.get(placeholder_list[i])
## 替换占位符
#row[title] = row[title].format(Array(oris[items.find(row)]))
file.close() # 读取完成后关闭文件
return items本文作者:晝行燈
版权声明:本文采用 CC BY-NC 4.0 协议授权
转载需注明作者及原文链接: https://mansifield.pages.dev/a7f4cx/