文章目录
- 环境配置
- 1 创建 YadeSheetData
- 2 读取方式
- 2.1 表格读取
- 2.2 列表读取
- 3 自定义设置
- 3.1 修改代码生成位置
- 3.2 添加列表支持
- 3.2.1 修改 DataTypeMapper.cs
- 3.2.2 修改 SheetDataExtensions.cs
- 3.2.3 修改 CodeGeneratorEditor.cs
- 3.2.4 测试
官方文档: Unity 亚德表 — Yade Sheet for Unity。
本文介绍基本使用方法与部分心得。
环境配置
- Unity 版本:6000.0.26f1c1
- YadeSheet 版本:1.5.5
1 创建 YadeSheetData
- 在 Project 窗口中右键单击并选择 创建
->
Yade Sheet 菜单以创建 yade 工作表文件,将其命名为 TestSheet 。
- 双击 TestSheet 文件开始编辑,例如:
2 读取方式
2.1 表格读取
- 创建名为 Test.cs 的 MonoBehaviour 脚本,声明 public 的 YadeSheetData 字段 sheet,在 Start 函数中打印表格中的内容。
using UnityEngine;
using Yade.Runtime;public class Test : MonoBehaviour
{public YadeSheetData Sheet;// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){// 读取第 0 行第 0 列的 CellDebug.Log(Sheet.GetCell(0, 0).GetValue()); // Result: "Hello"// 读取 B1 CellDebug.Log(Sheet.GetCell("B1").GetValue()); // Result: "Samples"}// Update is called once per framevoid Update(){ }
}
- 在场景中创建空物体 Test 并挂载 Test.cs 脚本,关联 TestSheet,运行后即可得到输出结果。
2.2 列表读取
这种读取方式将表格中的每一行看做一个 Item
,整个表格即为 List<Item>
。
-
创建 Item 的 C# 数据结构。
依次点击 “1”
->
“2”,创建 Item 的字段。- Index:要设置的列。
- Alias:简短描述。
- 。Field:用于内置代码生成器生成类的 Field 名,只能输入只能与数字、字母和
_
组合的单词,不能以数字开头 - Type:用于内置代码生成器生成类中字段的类型。
- 在标题区右键,可选择显示 Type、Field、Alias。
- 依次点击 “1”
->
“2”,输入要生成的 C# 代码名,下方有预览。
-
点击生成,默认生成在 “Asset”
->
“Yade”->
“CodeGen” 目录下。[DataField(0)]
特性表示 Name 对应第 0 列的数据。
using System;
using Yade.Runtime;public class Data
{/// <summary>/// 字符串1/// </summary>[DataField(0)] public String Name;/// <summary>/// 字符串2/// </summary>[DataField(1)] public String Content;[DataField(2)] public String _C;[DataField(3)] public String _D;[DataField(4)] public String _E;[DataField(5)] public String _F;[DataField(6)] public String _G;
}// Generated by Yade (http://u3d.as/1VtP)
- 接下来,即可将 TestSheet 转换为 List 进行读取:
using UnityEngine;
using Yade.Runtime;public class Test : MonoBehaviour
{public YadeSheetData Sheet;// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){List<Data> list = Sheet.AsList<Data>();Debug.Log(list[2].Name); // Result: "Hello2"Debug.Log(list[3].Content); // Result: "Samples3"}// Update is called once per framevoid Update(){ }
}
3 自定义设置
3.1 修改代码生成位置
依据路径 “Asset” ->
“Yade” ->
“Editor” ->
“Components” ->
“Common”,找到目录下的 “CodeGeneratorEditor.cs” 代码文件。
在第 286 行的 Create() 方法中修改默认生成路径。
3.2 添加列表支持
原生支持类型如下,可以看到,有许多不必要且不常用的类型(最后一行为自定义扩展类)。
3.2.1 修改 DataTypeMapper.cs
依据路径 “Asset” ->
“Yade” ->
“Runtime” ->
“Common”,找到目录下的 “DataTypeMapper.cs” 代码文件。
第 66 行 ~ 91 行定义了支持的内置类型。
许多不常用,我们修改如下(注意保持排序):
3.2.2 修改 SheetDataExtensions.cs
依据路径 “Asset” ->
“Yade” ->
“Runtime” ->
“Extensions”,找到目录下的 “SheetDataExtensions.cs” 代码文件。
第 65 行 ~ 80 行给出了对应类型的转换器 Parser。
同样,修改如下。
同时,创建对应的转换方法即可。这里我使用 “|” 分隔元素。
private static List<string> ListStringParse(string arg)
{var list = new List<string>();var strs = arg.Split('|');foreach (var str in strs){list.Add(str.TrimStart().TrimEnd());}return list;
}private static List<float> ListFloatParse(string arg)
{var list = new List<float>();var strs = arg.Split('|');foreach (var str in strs){list.Add(Convert.ToSingle(str.TrimStart().TrimEnd()));}return list;
}private static List<int> ListIntParse(string arg)
{var list = new List<int>();var strs = arg.Split('|');foreach (var str in strs){list.Add(Convert.ToInt32(str.TrimStart().TrimEnd()));}return list;
}
回到编辑器页面,可以看到添加了 List 类型,同时删除了许多不常用的内置类型。
之后,将第 253 ~ 275 行注释,这段代码会捕获 List 类型,导致转换失败。注释后 List 类型会直接进入第 278 行的 else 块中,这段代码将正确处理 List 类型。
3.2.3 修改 CodeGeneratorEditor.cs
到此并没有结束,生成代码时,发现 List 类型不正确:
这和 CodeGen 有关,因此,我们回到 “Asset” ->
“Yade” ->
“Editor” ->
“Components” ->
“Common”,找到目录下的 “CodeGeneratorEditor.cs” 代码文件。在第 180 行 ~ 190 行的 GetCodeGenerated() 函数中,没有处理泛型类型的情况。
替换为如下代码,同时在 “CodeGeneratorEditor.cs” 中导入 System.Array
命名空间:
var typeString = type.ToString();
if (type.IsGenericType)
{// 获取类型的名称,不包括泛型参数的部分string baseName = type.GetGenericTypeDefinition().Name;// 去掉类型名称中的数字,例如 List`1 -> ListbaseName = baseName.Substring(0, baseName.IndexOf('`'));// 获取泛型参数的类型名称,并去掉其命名空间部分var genericArgs = type.GetGenericArguments();string genericArgsStr = "<" + string.Join(", ", Array.ConvertAll(genericArgs, t => t.Name)) + ">";typeString = baseName + genericArgsStr;
}
else if (typeString.Contains("+"))
{var temp = typeString.Split(new char[] { '+' }, System.StringSplitOptions.RemoveEmptyEntries);namespaces.AppendLine(string.Format("using static {0};", temp[0]));typeString = temp[1];
}
else if (typeString.StartsWith("System."))
{typeString = typeString.Substring(7);
}
最后,还需要在第 156 行添加命名空间 “System.Collections.Generic” 的写入,以在生成代码中支持泛型类的使用。
3.2.4 测试
以如下表格为例,生成到 Data.cs 文件中。
打开 Data.cs 代码,没有报错。
重新修改 Test.cs 脚本,运行,成功读取 List。
using System.Collections.Generic;
using UnityEngine;
using Yade.Runtime;public class Test : MonoBehaviour
{public YadeSheetData Sheet;public List<float> Content1;public List<float> Content2;public List<float> Content3;public List<float> Content4;// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){var list = Sheet.AsList<Data>();foreach (var data in list){Debug.Log(data.Name);}Content1 = list[0].Content;Content2 = list[1].Content;Content3 = list[2].Content;Content4 = list[3].Content;}// Update is called once per framevoid Update(){ }
}