此网站域名即将过期,小程序开发流程步骤,网站开发需要文章写的好吗,wordpress语言编程吗Unity读取表格数据
效果#xff1a; 思路#xff1a;
Unity可以解析Json#xff0c;但是读取Excel需要插件的帮助#xff0c;那就把这个功能分离开#xff0c;读表插件就只管读表转Json#xff0c;Unity就只管Json解析#xff0c;中间需要一个存储空间#xff0c;使用…Unity读取表格数据
效果 思路
Unity可以解析Json但是读取Excel需要插件的帮助那就把这个功能分离开读表插件就只管读表转JsonUnity就只管Json解析中间需要一个存储空间使用ScriptableObject数据类是个不错的选择。
缺点也很明显我们只能在Unity编辑器模式下使用这个工具也就是无法在打包后读取Excel不过我们再也不用担心读表插件出问题了因为打包后根本用不到读表插件。
实现步骤
步骤一Excel数据转换成Json数据步骤二将数据存储到ScriptableObject持久类中步骤三Unity读取ScriptableObject类
Excel数据转换成Json数据
因为只考虑在Unity编辑器模式使用所以直接写一个编辑器窗口就行了 主要功能概述
用户界面EditorWindow提供一个界面让用户选择 Excel 文件并进行相应的操作如选择是否生成 C# 类文件、开始转换等。文件处理用户可以拖拽文件或文件夹到指定区域程序会识别路径并加载 Excel 文件列表。转换操作Excel 文件被读取转换为 JSON 数据并保存到指定路径。
打开编辑窗口
[MenuItem(Tools/ExcelToJson)]
public static void ShowWindow()
{ExcelToUnityWindow window GetWindowExcelToUnityWindow(Excel 转 Json 工具);window.minSize new Vector2(400 , 300);
}这段代码创建了一个编辑器窗口当用户点击 Unity 编辑器菜单中的 “Tools/ExcelToJson” 时会弹出 ExcelToUnityWindow 窗口。
初始化并加载 JsonFileData
private void OnEnable()
{csOutputPath Path.Combine(Application.dataPath , Tool/ExcelTool/ConfigData);jsonFileCollector Resources.LoadJsonFileData(JsonFileCollector);if (jsonFileCollector null)Debug.LogError(未找到 JsonFileCollector 实例请确保已创建该资产文件);RefreshFileList();
}OnEnable 方法会在编辑器窗口启用时调用它会加载 JsonFileCollector 实例这个实例用于管理 JSON 数据。
文件夹路径选择与拖拽支持
private void HandleDragAndDrop(Rect dropArea)
{Event evt Event.current;if (evt.type EventType.DragUpdated || evt.type EventType.DragPerform){if (dropArea.Contains(evt.mousePosition)){DragAndDrop.visualMode DragAndDropVisualMode.Copy;if (evt.type EventType.DragPerform){DragAndDrop.AcceptDrag();if (DragAndDrop.paths.Length 0){string draggedPath DragAndDrop.paths[0];if (File.Exists(draggedPath) draggedPath.EndsWith(.xlsx)){folderPath Path.GetDirectoryName(draggedPath);}else if (Directory.Exists(draggedPath)){folderPath draggedPath;}RefreshFileList();}evt.Use();}}}
}这个方法实现了拖拽功能用户可以将文件或文件夹拖拽到指定区域程序会检测并更新路径。
转换文件的核心操作
private void ConvertExcelFiles()
{foreach (string filePath in selectedExcelFiles){ParseFile(filePath , createCS , csOutputPath);}EditorUtility.DisplayDialog(完成 , 所有 Excel 文件已成功转换 , 确定);
}
ConvertExcelFiles() 方法会遍历用户选择的 Excel 文件并调用 ParseFile() 方法来处理每一个文件。这个方法的核心功能是将 Excel 文件转换为 JSON 格式。
Excel 文件解析与 JSON 转换
private static string ParseFile(string path , bool createCS , string csOutputPath)
{if (!path.EndsWith(xlsx)) return null;string tableName ;string cfgName ;Excel excel null;try{(Excel a, string b) temp ExcelHelper.LoadExcel(path);excel temp.a;cfgName temp.b;StringBuilder sb new StringBuilder();JsonWriter writer new JsonWriter(sb);writer.WriteObjectStart();foreach (ExcelTable table in excel.Tables){tableName table.TableName;if (tableName.StartsWith(#)) continue;if (createCS){try{Debug.Log($生成 C# 类文件{csOutputPath});ExcelDeserializer deserializer new ExcelDeserializer{FieldNameLine 1,FieldTypeLine 2,FieldValueLine 3,IgnoreSymbol #,ModelPath ${Application.dataPath}/Tool/ExcelTool/Editor/Excel/ExcelToUnity/DataItem.txt};deserializer.GenerateCS(table, cfgName, csOutputPath); // 生成 C# 文件}catch (System.Exception ex){Debug.LogError($生成 C# 类文件时出错: {ex.Message});return null;}}writer.WritePropertyName(Config);writer.WriteArrayStart();for (int i 4; i table.NumberOfRows; i){string idStr table.GetValue(i, 1)?.ToString();if (string.IsNullOrEmpty(idStr)) break;writer.WriteObjectStart();for (int j 1; j table.NumberOfColumns; j){string propName table.GetValue(1, j)?.ToString()?.Replace(*, );string propType table.GetValue(2, j)?.ToString();if (string.IsNullOrEmpty(propName) || propName.StartsWith(#)) continue;writer.WritePropertyName(propName);string value table.GetValue(i, j)?.ToString();if (propType int){writer.Write(int.TryParse(value, out int intValue) ? intValue : 0);}else if (propType bool){writer.Write(value 1 || value.ToLower() true);}else if (propType float){writer.Write(float.TryParse(value, out float floatValue) ? floatValue : 0);}else{writer.Write(value);}}writer.WriteObjectEnd();}writer.WriteArrayEnd();}writer.WriteObjectEnd();string outputDir Path.Combine(Application.streamingAssetsPath, DataFiles);if (!Directory.Exists(outputDir)) Directory.CreateDirectory(outputDir);string outputPath Path.Combine(outputDir, Path.GetFileNameWithoutExtension(path) .json);File.WriteAllText(outputPath, sb.ToString());Debug.Log(转换成功路径 outputPath);return sb.ToString();}catch (System.Exception ex){Debug.LogError($转换文件 {path} 时出错: {ex.Message});return null;}
}
这是处理 Excel 转 JSON 的关键方法。主要流程如下
加载 Excel 文件使用 ExcelHelper.LoadExcel() 方法加载 Excel 文件。遍历表格对于每个表格程序会遍历表格中的行和列将数据转换成适当类型int, bool, float, string。生成 JSON利用 JsonWriter 将表格中的数据按格式写入 JSON 格式。保存文件生成的 JSON 数据被保存到 DataFiles 文件夹中。
将数据存储到ScriptableObject持久类中。
准备存储Json数据 [System.Serializable]public class JsonData{[HideInInspector]public string FileName;public string Parent;public string Title;public JsonData(string fileName , string parent , string title){FileName fileName;Parent parent;Title title;}}[System.Serializable]public class ConfigData{public string configName;public int propertyCount;public string data;public ConfigData(string configName , int propertyCount){this.configName configName;this.propertyCount propertyCount;}}[Header(JSON 文件信息列表)][Tooltip(每个 JSON 文件的 Json数据)]public ListConfigData jsonDataList new ListConfigData();[Tooltip(每个 JSON 文件的 Parent 和 Title 字段)]public ListJsonData jsonPropertyList new ListJsonData();首先遍历目标路径查找所有 JSON 文件并解析其内容
public void RefreshJsonFileList()
{jsonDataList.Clear();jsonPropertyList.Clear(); // 清空列表if (!Directory.Exists(dataFilesPath)){Debug.LogError($目标路径不存在: {dataFilesPath});return;}string[] files Directory.GetFiles(dataFilesPath, *.json);if (files.Length 0){Debug.LogWarning(未找到任何 JSON 文件.);}foreach (var file in files){string fileName Path.GetFileNameWithoutExtension(file);int propertyCount GetJsonFilePropertyCount(file);jsonDataList.Add(new ConfigData(fileName, propertyCount));ReadJsonFile(file, fileName);}Debug.Log($找到 {jsonDataList.Count} 个 JSON 文件.);
}
Directory.GetFiles 查找文件夹中的 .json 文件。GetJsonFilePropertyCount 获取每个文件中 Config 数组中第一个对象的属性数量。ReadJsonFile 解析 JSON 文件提取 Parent 和 Title 信息。
读取 JSON 文件内容
public void ReadJsonFile(string file, string fileName)
{string jsonContent File.ReadAllText(file);JObject jsonObject null;try{jsonObject JObject.Parse(jsonContent);}catch (System.Exception ex){Debug.LogError($解析文件失败: {file}, 错误: {ex.Message});return;}JArray configArray jsonObject[Config] as JArray;if (configArray ! null){foreach (var configItem in configArray){string parent configItem[Parent]?.ToString();string title configItem[Title]?.ToString();if (!string.IsNullOrEmpty(parent) !string.IsNullOrEmpty(title)){jsonPropertyList.Add(new JsonData(fileName, parent, title));}}}
}
使用 File.ReadAllText 读取文件内容。通过 JObject.Parse 解析 JSON 字符串。查找 Config 数组中的每个元素提取 Parent 和 Title并将其与文件名一起保存为 JsonData 对象。
获取 JSON 文件的属性数量方便分类
int GetJsonFilePropertyCount(string file)
{string jsonContent File.ReadAllText(file);JObject jsonObject null;try{jsonObject JObject.Parse(jsonContent);}catch (System.Exception ex){Debug.LogError($解析文件失败: {file}, 错误: {ex.Message});return 0;}JArray configArray jsonObject[Config] as JArray;if (configArray null || configArray.Count 0){Debug.LogWarning($文件 {file} 中没有找到有效的 Config 数组。);return 0;}return configArray[0].ChildrenJProperty().Count();
}
读取 JSON 文件并解析为 JObject。获取 Config 数组的第一个元素并统计其属性数量。
加载和保存 JSON 数据
加载 JSON 数据GetJsonData() 和 LoadConfig() 方法批量加载 JSON 数据
public void GetJsonData()
{
#if UNITY_EDITORcfgProgress 0;string filepath ConfigManager.GetStreamingAssetsPath();foreach (var item in jsonDataList){string configPath $DataFiles/{item.configName}.json;LoadConfig(item, configPath, filepath, jsonDataList.Count);}
#endif
}void LoadConfig(ConfigData configData, string configPath, string filepath, int Count, Action OnConfigLoaded null)
{
#if UNITY_EDITORstring filePath Path.Combine(filepath, configPath);try{if (File.Exists(filePath)){string fileContent File.ReadAllText(filePath);configData.data fileContent;cfgProgress;if (cfgProgress Count){OnConfigLoaded?.Invoke();}}else{Debug.LogError($文件不存在: {filePath});}}catch (Exception ex){Debug.LogError($加载配置表时发生错误: {ex.Message});}
#endif
}
保存实例
public void SaveInstance()
{
#if UNITY_EDITOREditorUtility.SetDirty(this); // 标记为已修改AssetDatabase.SaveAssets(); // 保存所有修改AssetDatabase.Refresh(); // 刷新数据库Debug.Log(JsonFileCollector 实例已保存.);
#endif
}
做一个编辑器面板用于手动读取保存数据
[CustomEditor(typeof(JsonFileData))]
public class JsonFileCollectorEditor : Editor
{public override void OnInspectorGUI(){JsonFileData collector (JsonFileData)target;DrawDefaultInspector();if (GUILayout.Button(刷新文件列表, GUILayout.Height(30))){collector.RefreshJsonFileList();collector.GetJsonData();collector.SaveInstance();}GUILayout.Space(10);if (collector.jsonDataList.Count 0){GUILayout.Label(未找到 JSON 文件.);}}
}
OK大概这样子 Unity读取ScriptableObject类
解析 JSON 数据 加载完 JSON 文件后你通常需要将字符串类型的 JSON 数据转换成实际的 C# 对象。这个过程通常依赖于第三方库如 Newtonsoft.Json 或 LitJson来解析。 可以通过 JsonMapper.ToObject 方法来自 LitJson 库将 JSON 字符串转换为指定类型的对象。 public ListT GetConfigRootT(){foreach (var item in jsonDataList){if (item.configName typeof(T).Name){ConfigRootT configRoot JsonMapper.ToObjectConfigRootT(item.data); // 解析 JSON 数据为对象return configRoot.Config;}}return null;}public ListT GetConfigRootT(string name){foreach (var item in jsonDataList){if (item.configName name){ConfigRootT configRoot JsonMapper.ToObjectConfigRootT(item.data);return configRoot.Config;}}return null;}通过上述步骤Unity 使用存储好的 JSON 数据的流程如下
存储 JSON 数据通过 ScriptableObject如 JsonFileData将 JSON 文件的数据存储在 ConfigData.data 字段中。加载 JSON 数据通过 GetJsonData() 和 LoadConfig() 方法从磁盘读取 JSON 文件内容并存储到内存中。解析 JSON 数据使用第三方库如 LitJson将 JSON 字符串转换为 C# 对象通常通过 JsonMapper.ToObject() 方法进行。使用数据将解析后的数据应用到游戏逻辑中如配置角色、武器、敌人等游戏元素。
通过这种方式你能够在 Unity 中灵活地管理和使用 JSON 配置数据。
如何使用
一般来说需要提供一个数据类一个表的名称就可以拿到里面的数据
例如
JsonFileData.GetConfigRoot数据类(文件名)不过如果有多张表相同的结构该怎么办
我们可以使用之前存储好的表名来遍历里面的数据使用属性数量来过滤出我们使用的数据
属性数量8 属性数量6 过滤出数据
foreach (var item in JsonFileData.jsonDataList)
{if (item.propertyCount6){foreach (var config in JsonFileData.GetConfigRootConfig_Default(item.configName)){Config_Default Default config;string info ;info ID: Default.ID;info 父节点: Default.Parent;info 标题: Default.Title;info 内容: Default.Content;info 图片路径: Default.SpritePath;info 视频路径: Default.VideoPath;Debug.Log(info);}}else{foreach (var config in ConfigHelper.GetConfigInfoConfig_Answer(item.configName)){Config_Answer Default config;string info ;info ID: Default.ID;info 父节点: Default.Parent;info 标题: Default.Title;info 内容: Default.OptionA;info Default.OptionB;info Default.OptionC;info Default.OptionD;info 答案: Default.CorrectAnswer;Debug.Log(info);}}
}使用属性数量过滤不是一个好的选择各位可以各显神通看看如何解决这个问题。
Demo下载链接 读表工具