-2

I am trying to parse a JSON with the following structure in my Unity C# script:

{
  "Location1": [
    {
      "text": "Hello!",
      "action": "wave"
    },
    {
      "text": "Welcome!",
    }
  ],
  "Location2": [
    {
      "text": "This will be fun.",
      "action": "talk"
    },
    {
      "text": "Let's go!",
      "action": "happy"
    }
  ]
}

As you can see, it is an object of type (I presume) Dictionary<string, List<Dictionary<string, string>>>. Note that "action" is optional.

I tried implementing classes to interpret the nesting, but no matter what combination or complexity I've gone, I can't seem to get a non-null dialogue.path.

using System.Collections.Generic;
using UnityEngine;
using TMPro;

[System.Serializable]
public class Event
{
    public string text;
    public string? action;
}

[System.Serializable]
public class Dialogue
{
    public Dictionary<string, List<Event>> path;
}

public class Sinterface : MonoBehaviour
{
    private Dialogue dialogue;

    void Start()
    {
        TextAsset json = Resources.Load<TextAsset>("my_dialogue");
        Functions.Log("JSON Loaded: " + json.text); // this works

        dialogue = JsonUtility.FromJson<Dialogue>(json.text);

        foreach (KeyValuePair<string, List<Event>> entry in dialogue.path) // NullReferenceException
        {
            Functions.Log("Location: " + entry.Key);
            foreach (Event e in entry.Value)
            {
                Functions.Log("Event Text: " + e.text);
                Functions.Log("Event Action: " + e.action);
            }
        }
    }
}

How do I properly "extract" these objects from my JSON into this C# script?

5
  • Deserialize as dictionary without the class. Dictionary<string, List<Event>> path = JsonUtility.FromJson<Dictionary<string, List<Event>>>(json.text); Commented Jan 9, 2024 at 1:30
  • Thanks @YongShun, I tried that typing in addition to trying with and without [System.Serializable] before the Event class. path.Keys.Count is 0 in both cases. Commented Jan 9, 2024 at 2:27
  • 2
    JsonUtility.FromJson() does not support dictionaries. See this answer by Programmer to Serialize and Deserialize Json and Json Array in Unity. But Unity now has an official port of Json.NET available. Install com.unity.nuget.newtonsoft-json from the package manager and you should be able to do JsonConvert.DeserializeObject<Dictionary<string, List<Event>>>(json.text). Commented Jan 9, 2024 at 3:06
  • Huge thanks, @dbc, that worked. I'll update my question/answer with details soon. Commented Jan 9, 2024 at 5:20
  • See this question gamedev.stackexchange.com/questions/162480/parse-json-in-unity Commented Jan 9, 2024 at 6:28

1 Answer 1

0

Thank you @dbc for educating me and advising the usage of NewtonsoftJSON (installation instructions here)

using UnityEngine;
using System.Collections.Generic;
using Newtonsoft.Json;

public class Sinterface : MonoBehaviour
{
    [SerializeField]
    private TextAsset jsonFile;

    [System.Serializable]
    public class Event
    {
        public string text;
        public string? action;
    }

    public Dictionary<string, List<Event>> dialogue;

    void Start()
    {
        if (jsonFile != null)
        {
            string jsonString = jsonFile.text;
            dialogue = JsonConvert.DeserializeObject<Dictionary<string, List<Event>>>(jsonString);
        }
        else
        {
            Debug.LogError("JSON file is not assigned in Unity Inspector");
        }

        foreach (string locationName in dialogue.Keys)
        {
            Debug.Log(locationName);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.