Encoding/decoding JSON

string text = File.ReadAllText(settingsFolder + "myFile.json");
dynamic myObject = JsonUtility.FromJson<string>(text);
Debug.Log(myObject);

Results in:

System.Dynamic.UpdateDelegates:UpdateAndExecuteVoid2(CallSite, Type, Object)
UnityInterface:Start() (at Assets/Scripts/Core/UnityInterface.cs:72)

But it has an empty line above it, it’s not null, it’s an empty string.

myFile.json, entirely copypasted:

{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

It’s just an example I copied from the Internet.

I expected a Dictionary, List or some form of JSON class. Instead I’ve got an empty string (not null). Link to ReadAllText is correct, otherwise (as tested) it would’ve thrown: DirectoryNotFoundException: Could not find a part of the path.

I can’t work with “NewtonSoft” thing because I already installed it and Visual Studio still tells me that such namespace doesn’t exist.
There’s also another thing which had “Web” in it’s namespace that had the same issue. I installed it, but it still wouldn’t budge.
Solutions were to include it in the solution by going through dependencies, which I’ve done, still no budge.

How do I put items in and out of JSON string?

I recommend reading what JsonUtility actually does instead of just assuming, because it’s not that at all. The docs have a good, straightforward example and everything.
(Some other Json packages do give you nested dictionaries, but JsonUtility explicitly does not do that for performance reasons.)

3 Likes

Funny you should say that, after I tried every non-Unity solution I sought for Unity one, I got this one directly from the docs. I read the first line: “Create an object from its JSON representation.” and then read the code:

using UnityEngine;

[System.Serializable]
public class PlayerInfo
{
    public string name;
    public int lives;
    public float health;

    public static PlayerInfo CreateFromJSON(string jsonString)
    {
        return JsonUtility.FromJson<PlayerInfo>(jsonString);
    }

    // Given JSON input:
    // {"name":"Dr Charles","lives":3,"health":0.8}
    // this example will return a PlayerInfo object with
    // name == "Dr Charles", lives == 3, and health == 0.8f.
}

I thought it created JSON into objects. Performance is not important, I will be using JSON to store and read player’s settings and potential mods to the game (for reasons of which PlayerPrefs is not enough). It’s meant to be read and written at most once for every launch.

What would be an actual way to read/write JSON data?

I can’t use NewtonSoft.Json (doesn’t react) or System.Web.Helpers (doesn’t exist) or System.Runtime.Serialization.Json (doesn’t contain the function) or System.Web.Script.Serialization (doesn’t contain the function) or JavaScriptSerializer (doesn’t contain the function).

You can use JsonUtility to read/write data, just not the way you’re doing it. You need to create a class (not a dynamic object) to do so, with the names and structure of the members of the class matching up with the names and structure of the JSON data, just like how “name”, “lives”, and “health” match up between the JSON input and the PlayerInfo class in the docs sample. The lower levels of the JSON structure (such as “glossDiv” in your first sample code) also need to be classes that match their own structure.

When you’ve created the classes, you’ll use the main class as the type parameter in FromJson(text). It will then use the YourClassNameHere’s class structure to know how to read the json data.

If you do need lists/dictionaries (lists meaning [“data”,“in”,“square”,“brackets”] like glossSeeAlso, dictionaries meaning that you don’t know the exact keys before you see the file, which doesn’t exist in your sample json), then LitJson is great, works the same way as JsonUtility (but supports list/dict), though it does generate GC (and therefore not good for ingame usage, performance wise).

1 Like
2 Likes

How important to you is it that it be JSON? Because GRFON, a much more easily understandable serialization format by @JoeStrout , does allow you to access data stored in it through the approach you’re describing.

https://discussions.unity.com/t/610809
https://app.assembla.com/wiki/show/grfon/Developer_Docs

1 Like