You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity中JSON多维数组反序列化问题求助及类结构优化

Unity JSON反序列化:处理多维数组问题

咱们先梳理下你现有代码的核心问题:你的C#类结构和JSON的层级不匹配,尤其是movesmonuments这两个数组的定义,这才导致多维数组解析失败。

问题拆解

  • JSON里的moves二维数组(数组嵌套数组):[[{},{}], [{},{}]],但你定义的List<Moves>是一个对象列表,每个对象里再包Move[],完全和JSON的结构对不上;
  • 你还没定义对应citiesmonuments的类结构,这部分自然也没法解析。

修正后的C#序列化类

下面是完全匹配你JSON结构的类,我调整了类名让语义更清晰,同时修正了多维数组的定义:

using System.Collections.Generic;
using UnityEngine;

// 顶层类,对应整个JSON的完整结构
[System.Serializable]
public class GameData
{
    public List<City> cities;
    public List<Puzzle> puzzles;
}

[System.Serializable]
public class City
{
    public string name;
    public List<Monument> monuments; // 匹配JSON里的monuments数组
}

[System.Serializable]
public class Monument
{
    public int levels;
    public string objBeingIntroduced;
}

[System.Serializable]
public class Puzzle
{
    public int puzzleId;
    public List<List<Move>> moves; // 二维列表,完美对应JSON的二维数组
    public List<Square> squares;
}

[System.Serializable]
public class Move
{
    public int x;
    public int y;
    public int xInc;
    public int yInc;
}

[System.Serializable]
public class Square
{
    public int x;
    public int y;
    public string type;
}

如何加载JSON数据

Unity自带的JsonUtility就能完成这个任务,但要注意它的一个限制:不能直接反序列化顶级数组,必须通过顶层类(比如上面的GameData)来包裹整个JSON结构。

方式1:从字符串加载

如果你的JSON是字符串形式(比如从网络获取或内嵌代码),可以这样做:

// 替换成你的JSON字符串内容
string jsonContent = "{ \"cities\": [{ \"name\": \"London\", ... }], \"puzzles\": [{ ... }] }";
GameData gameData = JsonUtility.FromJson<GameData>(jsonContent);

// 测试访问解析后的数据
if (gameData.puzzles.Count > 0)
{
    Puzzle firstPuzzle = gameData.puzzles[0];
    Debug.Log($"第一个谜题ID:{firstPuzzle.puzzleId}");
    // 访问第一组移动指令
    List<Move> firstMoveGroup = firstPuzzle.moves[0];
    foreach (Move move in firstMoveGroup)
    {
        Debug.Log($"移动坐标:x={move.x}, y={move.y}");
    }
}

// 测试访问城市和纪念碑数据
if (gameData.cities.Count > 0)
{
    City london = gameData.cities[0];
    Debug.Log($"城市名称:{london.name}");
    foreach (Monument monument in london.monuments)
    {
        Debug.Log($"纪念碑等级:{monument.levels}");
    }
}

方式2:从本地文件加载

如果JSON文件放在Resources文件夹下,可以这样读取:

TextAsset jsonFile = Resources.Load<TextAsset>("你的JSON文件名(不要带后缀)");
if (jsonFile != null)
{
    GameData gameData = JsonUtility.FromJson<GameData>(jsonFile.text);
    // 后续处理逻辑和上面一致
}

额外小提示

如果需要更灵活的JSON处理(比如支持大小写不匹配、更复杂的嵌套结构),可以考虑用Newtonsoft.Json for Unity(Unity官方适配的版本),它能处理更多边缘情况,不过需要先在Package Manager里安装这个包。

内容的提问来源于stack exchange,提问作者Cypras

火山引擎 最新活动