使用JsonUtility反序列化嵌套对象

时间:2019-09-01 05:44:56

标签: c# json unity3d

我想反序列化保存有关级别信息的json文件。给定此示例的.json文件称为 1.json

{
  "name": "Level One",
  "map": [
    [{
      "groundTexture": "grass",
      "cellType": "empty",
      "masterField": null,
      "worldObjects": [{
        "worldObjectType": "player",
        "rotation": 90
      }]
    },{
      "groundTexture": "grass",
      "cellType": "obstacle",
      "masterField": null,
      "worldObjects": [{
        "worldObjectType": "tree",
        "rotation": 0
      }]
    }],[{
      "groundTexture": "grass",
      "cellType": "campFire",
      "masterField": null,
      "worldObjects": [{
        "worldObjectType": "campfire",
        "rotation": 270
      }]
    },{
      "groundTexture": "grass",
      "cellType": "related",
      "masterField": {
          "x": 1,
          "y": 0
      },
      "worldObjects": []
    }]
  ]
}

我想将数据从该文件转换为一个类对象,其中包含在运行时创建关卡所需的所有数据。我创建了一个只读取文件内容的阅读器

public class LevelReader : MonoBehaviour
{
    private string levelBasePath;

    private void Awake()
    {
        levelBasePath = $"{Application.dataPath}/ExternalFiles/Levels";
    }

    public string GetFileContent(string levelName)
    {
        string file = $"{levelName}.json";
        string filePath = Path.Combine(levelBasePath, file);
        return File.ReadAllText(filePath);
    }
}

和一个将json字符串映射到LevelInfo对象的映射器。

public class LevelMapper : MonoBehaviour
{
    private void Start()
    {
        // DEBUGGING TEST

        LevelReader levelReader = GetComponent<LevelReader>();
        string levelContent = levelReader.GetFileContent("1");
        LevelInfo levelInfo = MapFileContentToLevelInfo(levelContent);

        Debug.Log(levelInfo.cells);
    }

    public LevelInfo MapFileContentToLevelInfo(string fileContent)
    {
        return JsonUtility.FromJson<LevelInfo>(fileContent);
    }
}

以下结构仅有助于创建包含所有级别数据的对象:

[Serializable]
public struct LevelInfo
{
    public string name;
    public LevelCell[][] cells;
}

[Serializable]
public struct LevelCell
{
    public string groundTexture;
    public string cellType;
    public Vector2? masterField;
    public LevelWorldObject[] worldObjects;
}

[Serializable]
public struct LevelWorldObject
{
    public string worldObjectType;
    public int rotation;
}

启动应用程序时,映射器将运行并循环遍历数据对象。不幸的是,单元格为空。如何正确反序列化文件?

1 个答案:

答案 0 :(得分:3)

  1. 在LevelInfo结构中,您具有字段“ cells”,但在Json中则是“ map”。它们必须相同。
  2. JsonUtility无法对多维数组进行序列化/反序列化。

https://answers.unity.com/questions/1322769/parsing-nested-arrays-with-jsonutility.html https://docs.unity3d.com/Manual/script-Serialization.html

我相信您可以更改数据结构或使用其他序列化器。