Question3r
Question3r

Reputation: 3752

Deserialize nested objects with JsonUtility

I would like to deserialize my json files holding information about levels. Given this example .json file called 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": []
    }]
  ]
}

I would like to convert the data from that file to a class object holding all the data needed to create a level during runtime. I created a reader which only reads the file content

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);
    }
}

and a mapper which maps the json string to a LevelInfo object.

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);
    }
}

The following structs just help to create an object containg all the level data:

[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;
}

When starting the application the mapper runs and loops through the data object. Unfortunately the cells are null. How can I deserialize the file correctly?

Upvotes: 1

Views: 1602

Answers (1)

Yauheni
Yauheni

Reputation: 316

  1. In LevelInfo structure you have field "cells" but in Json - "map". They must be the same.
  2. JsonUtility can't serialize/deserialize multidimensional arrays.

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

I believe you can change your data structures or use another serializer.

Upvotes: 3

Related Questions