Unity C#使用JsonUtility解析JSON嵌套数组报空引用问题求助
问题根因
你两次解析失败都是踩了Unity内置JsonUtility的序列化规则限制,没有其他复杂原因:
- 第一次定义
List<string[]>类型的content字段:JsonUtility原生不支持嵌套集合类型的序列化/反序列化,不管是数组套数组、List套数组还是List套List,这类二维集合结构它都识别不了,解析完对应字段会直接返回null。 - 第二次改成
SingleArr[]结构依然失败:核心问题是你自定义的SingleArr和dialog类都没有加[System.Serializable]特性,JsonUtility会直接忽略没有标记这个特性的自定义类型,自然读不到数据。
可用解决方法
方案1:无需插件,适配你修改后的JSON结构
这个方案不需要引入第三方库,只要修正类的定义,补上序列化特性即可,代码如下:
using System; using UnityEngine; // 自定义类型必须加Serializable特性,否则JsonUtility无法识别 [Serializable] public class SingleLine { // 字段名必须和JSON里的键名完全一致,大小写敏感 public string[] list; } [Serializable] public class Dialog { public string name; public SingleLine[] content; }
解析逻辑和你之前写的一致,建议加上编码指定避免西语字符乱码:
public Dialog dial; // 解析前可以先校验文件是否存在,排除路径错误问题 if (File.Exists(jsonPath)) { string jsonText = File.ReadAllText(jsonPath, System.Text.Encoding.UTF8); dial = JsonUtility.FromJson<Dialog>(jsonText); } else { Debug.LogError($"JSON文件不存在,路径:{jsonPath}"); }
注意:字段名必须和JSON键完全匹配,比如你JSON里content数组里的对象键是
list,类里对应的字段名就必须是list,不能改成别的名字,否则会读取失败。
方案2:保留最开始的二维数组JSON结构
如果你不想修改最初的JSON格式,JsonUtility本身是不支持直接解析二维数组的,有两个选择:
- 引入轻量JSON解析库,这类库没有嵌套集合的限制,可以直接把
content解析为List<string[]>类型,不需要改JSON结构也不需要额外包装类。 - 用逐节点解析的方式手动读数据,不需要额外包装类,示例逻辑:
// 以通用轻量JSON节点解析逻辑为例 var jsonData = JSON.Parse(File.ReadAllText(jsonPath, Encoding.UTF8)); Dialog dial = new Dialog(); dial.name = jsonData["name"]; var contentArray = jsonData["content"].AsArray; dial.content = new List<string[]>(); for (int i = 0; i < contentArray.Count; i++) { var lineNode = contentArray[i].AsArray; string[] currentLine = new string[lineNode.Count]; for (int j = 0; j < lineNode.Count; j++) { currentLine[j] = lineNode[j]; } dial.content.Add(currentLine); }
空引用排查补充
如果改完代码还是报空,按顺序检查:
- 先确认JSON文件路径正确,用
File.Exists(jsonPath)校验,路径错误读不到文本的话解析肯定失败 - 检查JSON格式合法性,有没有缺引号、多逗号之类的语法错误
- 不要给用于序列化的类写带参数的构造函数,Unity序列化系统不支持这类类的实例化
内容的提问来源于stack exchange,提问作者Martin Jose Morata Garcia
相关产品推荐
相关产品推荐

