You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:33:22