Unity3D解析JSON文件输出Null值,请求排查问题原因
问题分析与解决方案
你的核心问题是C#类结构和JSON的实际格式完全不匹配,导致Newtonsoft.Json无法正确解析数据,出现输出0或报错的情况。
先拆解你的JSON结构
你的JSON是嵌套字典结构,最外层是一个以字符串数字为键的字典,每个键对应的值又是一个字典,内层字典的键同样是字符串数字,对应的值是包含4个元素的数组:
{ "0":{ "0":[ "56_Tele", "Castle Spire", 0, 21 ], "1":[ "44_Reflecto", "Did you remember?", 1, 18 ] } }
而你定义的WorldData类期望的是包含WorldId和Scenes数组的对象,JSON里根本没有这两个字段,自然解析不出数据。
方案1:适配现有JSON的C#代码
不需要修改JSON,调整C#类和解析逻辑即可:
1. 定义匹配数组结构的场景数据类
给WorldSceneData添加一个能从数组构造的构造函数,让Newtonsoft.Json知道如何把数组转成对象:
public class WorldSceneData { public string SceneName { get; set; } public string LevelName { get; set; } public uint MapXCoord { get; set; } public uint MapYCoord { get; set; } // 用于JSON数组解析的构造函数 [JsonConstructor] public WorldSceneData(string sceneName, string levelName, uint mapX, uint mapY) { SceneName = sceneName; LevelName = levelName; MapXCoord = mapX; MapYCoord = mapY; } }
2. 用字典结构解析整个JSON
因为JSON的键是动态的字符串数字,用Dictionary<string, Dictionary<string, WorldSceneData>>来匹配最外层和内层的字典:
private void Start() { // 解析JSON为嵌套字典 var worldDictionary = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, WorldSceneData>>>(json_data.text); // 示例:读取第一个世界的第一个场景数据 if (worldDictionary.TryGetValue("0", out var firstWorld)) { if (firstWorld.TryGetValue("0", out var firstScene)) { Debug.Log($"场景名:{firstScene.SceneName},关卡名:{firstScene.LevelName}"); Debug.Log($"坐标:X={firstScene.MapXCoord}, Y={firstScene.MapYCoord}"); } } }
方案2:修改JSON为面向对象格式(更推荐)
如果可以调整JSON结构,改成更清晰的面向对象格式,后续维护更方便:
修改后的JSON
{ "worlds": [ { "worldId": 0, "scenes": [ { "sceneId": 0, "sceneName": "56_Tele", "levelName": "Castle Spire", "mapXCoord": 0, "mapYCoord": 21 }, { "sceneId": 1, "sceneName": "44_Reflecto", "levelName": "Did you remember?", "mapXCoord": 1, "mapYCoord": 18 } ] } ] }
对应的C#类
public class RootData { public List<WorldData> Worlds { get; set; } } public class WorldData { public uint WorldId { get; set; } public List<SceneData> Scenes { get; set; } } public class SceneData { public uint SceneId { get; set; } public string SceneName { get; set; } public string LevelName { get; set; } public uint MapXCoord { get; set; } public uint MapYCoord { get; set; } }
解析代码
private void Start() { var rootData = JsonConvert.DeserializeObject<RootData>(json_data.text); // 读取第一个世界的第一个场景 var firstScene = rootData.Worlds[0].Scenes[0]; Debug.Log(firstScene.SceneName); Debug.Log(firstScene.LevelName); }
额外注意点
- 你注释掉的
[System.Serializable]属性对Newtonsoft.Json无效,这是Unity自带JsonUtility才需要的,用Newtonsoft的话可以直接删掉。 - 原来的代码中
Scenes数组会被解析为null,所以访问idstruct.Scenes[0]会直接报错,这就是你遇到的异常原因。
内容的提问来源于stack exchange,提问作者Alex Weber
相关产品推荐
相关产品推荐

