Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Json utility - save and load a list

Discussion in 'Scripting' started by ItzChris92, Aug 15, 2017.

  1. ItzChris92

    ItzChris92

    Joined:
    Apr 26, 2017
    Posts:
    365
    As the title says.

    If I have a class:

    public class MyList
    {
    public List <SomeClass> class;
    }

    How can I check if a json file exists, and if not create one? And then how can I load this list, and save it when I need to? I've read up on JSON Utility but can't figure out how to get a list to save and load correctly.

    Also, on topic, I know json utility works with Lists, but how does it handle serializing derived classes? For example, using the code above, if I had a public class SomeClass, and then a public class OtherClass : SomeClass and the list above contained both of these.
     
  2. rcenzo

    rcenzo

    Joined:
    Aug 21, 2014
    Posts:
    13
    Use File.Exists(...) to check if a file already exists. If you wish to write a Json file, you'd do something like this:
    var class = new MyList();
    var outputString = JsonUtility.ToJson(class);
    File.WriteAllText("C:\\MyFile.json", outputString);


    In reverse, you can deserialize anything doing this:

    var inputString = File.ReadAllText("C:\\MyFile.json");
    var class = JsonUtility.FromJson<MyList>(inputString);
     
  3. rcenzo

    rcenzo

    Joined:
    Aug 21, 2014
    Posts:
    13
    Oh, and on the topic of derived classes: you might as well just try it out for yourself, but if something's public in a root type, it's still public in the derived class and JsonUtility will be able to read/write from it.
     
  4. ItzChris92

    ItzChris92

    Joined:
    Apr 26, 2017
    Posts:
    365
    Thank you very much for your reply. Very concise! I will try this when I get home.

    On the topic of derived classes, what I meant was; normally to populate my list I would do:

    Code (CSharp):
    1. Add (new SomeClass(constructor variables here));
    Or:

    Code (CSharp):
    1. Add (new OtherClass  (constructor variables here));
    I know unity's serializer struggles to deserialize derived classes, and they deserialize as the parent class type. Do you still have this problem using JSON UTILITY?
     
    OrenBaba likes this.
  5. rcenzo

    rcenzo

    Joined:
    Aug 21, 2014
    Posts:
    13
    I work with deserialization a lot, but I can't say I have been working with the JsonUtility and deserialization of derived types that much. Maybe it's a good idea to create a demo project which tests only that. I'd try it for you right now, but I've got some other bugfixing to do :)
     
  6. ItzChris92

    ItzChris92

    Joined:
    Apr 26, 2017
    Posts:
    365
    Okay so I got this working, however I was right about the derived class issue. Going to try and derive from ScriptableObject and see if this fixes the issue
     
    Last edited: Aug 16, 2017
  7. rcenzo

    rcenzo

    Joined:
    Aug 21, 2014
    Posts:
    13
    Seems weird that you wouldn't be able to. In the message you made before you edited it you should try to make a wrapping class containing the array, and (de)serializing that instead.

    Code (CSharp):
    1. [System.Serializable]
    2. public class WrappingClass {
    3.     public List<Item> Inventory;
    4. }
    5. var variable  = new WrappingClass() { Inventory = someOtherList };
    6. JsonUtility.ToJson(variable);
    I'm not too sure about JsonUtility being able to directly convert a list or array to a generic Json array.
     
    petey and jeremy_crowell like this.
  8. petey

    petey

    Joined:
    May 20, 2009
    Posts:
    1,491
    Hiya, hey I've been using this quite a bit for saving and loading through json, it's really handy.
    Just wondering, is there a way to make the list generic? It's just that I've ended up with a bunch of different wrapping classes for different types and It would be nice to just have one generic one.
     
unityunity