您的位置:首页 > 娱乐 > 八卦 > 市场调研公司和咨询公司_工商公示信息查询系统官网_一个平台怎么推广_爱站网

市场调研公司和咨询公司_工商公示信息查询系统官网_一个平台怎么推广_爱站网

2024/12/28 1:46:43 来源:https://blog.csdn.net/CTangZe/article/details/144698178  浏览:    关键词:市场调研公司和咨询公司_工商公示信息查询系统官网_一个平台怎么推广_爱站网
市场调研公司和咨询公司_工商公示信息查询系统官网_一个平台怎么推广_爱站网

Unity读取表格数据

效果:

请添加图片描述

思路:

Unity可以解析Json,但是读取Excel需要插件的帮助,那就把这个功能分离开,读表插件就只管读表转Json,Unity就只管Json解析,中间需要一个存储空间,使用ScriptableObject数据类是个不错的选择。
缺点也很明显,我们只能在Unity编辑器模式下使用这个工具,也就是无法在打包后读取Excel,不过我们再也不用担心读表插件出问题了,因为打包后根本用不到读表插件。
实现步骤:
  • 步骤一:Excel数据转换成Json数据
  • 步骤二:将数据存储到ScriptableObject持久类中
  • 步骤三:Unity读取ScriptableObject类

Excel数据转换成Json数据

因为只考虑在Unity编辑器模式使用,所以直接写一个编辑器窗口就行了

在这里插入图片描述

主要功能概述
  • 用户界面(EditorWindow):提供一个界面让用户选择 Excel 文件,并进行相应的操作,如选择是否生成 C# 类文件、开始转换等。
  • 文件处理:用户可以拖拽文件或文件夹到指定区域,程序会识别路径并加载 Excel 文件列表。
  • 转换操作:Excel 文件被读取,转换为 JSON 数据,并保存到指定路径。
  1. 打开编辑窗口
[MenuItem("Tools/ExcelToJson")]
public static void ShowWindow()
{ExcelToUnityWindow window = GetWindow<ExcelToUnityWindow>("Excel 转 Json 工具");window.minSize = new Vector2(400 , 300);
}

这段代码创建了一个编辑器窗口,当用户点击 Unity 编辑器菜单中的 “Tools/ExcelToJson” 时,会弹出 ExcelToUnityWindow 窗口。

  1. 初始化并加载 JsonFileData
private void OnEnable()
{csOutputPath = Path.Combine(Application.dataPath , "Tool/ExcelTool/ConfigData");jsonFileCollector = Resources.Load<JsonFileData>("JsonFileCollector");if (jsonFileCollector == null)Debug.LogError("未找到 JsonFileCollector 实例,请确保已创建该资产文件!");RefreshFileList();
}

OnEnable 方法会在编辑器窗口启用时调用,它会加载 JsonFileCollector 实例,这个实例用于管理 JSON 数据。

  1. 文件夹路径选择与拖拽支持
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();}}}
}

这个方法实现了拖拽功能,用户可以将文件或文件夹拖拽到指定区域,程序会检测并更新路径。

  1. 转换文件的核心操作
private void ConvertExcelFiles()
{foreach (string filePath in selectedExcelFiles){ParseFile(filePath , createCS , csOutputPath);}EditorUtility.DisplayDialog("完成" , "所有 Excel 文件已成功转换!" , "确定");
}

ConvertExcelFiles() 方法会遍历用户选择的 Excel 文件,并调用 ParseFile() 方法来处理每一个文件。这个方法的核心功能是将 Excel 文件转换为 JSON 格式。

  1. 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 List<ConfigData> jsonDataList = new List<ConfigData>();[Tooltip("每个 JSON 文件的 Parent 和 Title 字段")]public List<JsonData> jsonPropertyList = new List<JsonData>();
首先遍历目标路径,查找所有 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].Children<JProperty>().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 List<T> GetConfigRoot<T>(){foreach (var item in jsonDataList){if (item.configName == typeof(T).Name){ConfigRoot<T> configRoot = JsonMapper.ToObject<ConfigRoot<T>>(item.data); // 解析 JSON 数据为对象return configRoot.Config;}}return null;}public List<T> GetConfigRoot<T>(string name){foreach (var item in jsonDataList){if (item.configName == name){ConfigRoot<T> configRoot = JsonMapper.ToObject<ConfigRoot<T>>(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.propertyCount==6){foreach (var config in JsonFileData.GetConfigRoot<Config_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.GetConfigInfo<Config_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下载链接👉 读表工具