Search Unity

  1. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  6. Unity 2017.3 beta is now available for download.
    Dismiss Notice

How to load an array with JsonUtility?

Discussion in 'Scripting' started by IntDev, Dec 23, 2015.

  1. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    I have a json array like this:
    Code (CSharp):
    1. [
    2.     {
    3.         "key": "here's the key",
    4.     },
    5.     {
    6.         "key": "here's the key",
    7.     }
    8. ]
    I try to load like this:
    Code (CSharp):
    1. [Serializable]
    2. public class Info
    3. {
    4.     public string key;
    5. }
    6.  
    7. var asset = Resources.Load<TextAsset>("JsonTest");
    8. var info = JsonUtility.FromJson<Info[]>(asset.text);
    But it says like this:
     
  2. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    Did you make the json yourself?
     
  3. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    yes
     
  4. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    is asset null by any chance?
     
  5. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    Nope ;)
     
  6. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
    try inheriting from System.Object
     
  7. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    Nothing different. If I print .Lenght it says 174090232 :eek:
     
  8. Polymorphik

    Polymorphik

    Joined:
    Jul 25, 2014
    Posts:
    599
  9. superpig

    superpig

    Insert bacon, receive bugfix Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    3,795
    Hi,

    We currently do not support array types for top-level JSON deserialization (like Info[]). You need to wrap the JSON in an object, like this:

    Code (csharp):
    1.  
    2. { "infos": [
    3.    { "key" : "key 1" },
    4.    { "key" : "key 2" }
    5. ] }
    6.  
    and then make a little wrapper class to match:
    Code (csharp):
    1.  
    2. [Serializable]
    3. public class InfosCollection
    4. {
    5.    public Info[] infos;
    6. }
    7.  
    8. JsonUtility.FromJson<InfosCollection>(...);
    9.  
    We know that this is not ideal and it's on the list to handle top-level arrays properly in the future.
     
  10. abdulthegamer

    abdulthegamer

    Joined:
    Sep 14, 2013
    Posts:
    4
    Thanks for the instructions Richard, Can you give an example on how to retrieve value for individual key such that a row has more than one key and its respective values. ?

    Ex :
    {
    "object":
    {
    "name": "nm",
    "place": "plc",
    "description": "dscrptn",
    },
    {
    "name": "nm",
    "place": "plc",
    "description": "dscrptn",
    },
    {
    "name": "nm",
    "place": "plc",
    "description": "dscrptn",
    },
    etc
    }
    How to access each values or say in a loop or something like that ?
     
    Last edited: Feb 3, 2016
  11. superpig

    superpig

    Insert bacon, receive bugfix Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    3,795
    Code (csharp):
    1.  
    2. [System.Serializable]
    3. public struct MyObject
    4. {
    5.    [System.Serializable]
    6.    public struct ArrayEntry
    7.    {
    8.       public string name;
    9.       public string place;
    10.       public string description;
    11.    }
    12.  
    13.    public ArrayEntry[] object;
    14. }
    15.  
     
    luisjesusmv and rakkarage like this.
  12. garrido86

    garrido86

    Joined:
    Dec 17, 2013
    Posts:
    154
    I made this helper method to wrap a json around a class, this way you don't need to change code on the server for accommodating the json top-level array problem .

    Code (CSharp):
    1.     public static string WrapToClass(this string source, string topClass){
    2.         return string.Format("{{ \"{0}\": {1}}}", topClass, source);
    3.     }
     
    Last edited: Mar 9, 2016
    Hiromichi-Yamada likes this.
  13. Meizi-Games

    Meizi-Games

    Joined:
    Nov 27, 2014
    Posts:
    4
    Took me a while to notice that FromJson doesn't work if the class members are defined as properties
     
    Artyom-Abgaryan likes this.
  14. superpig

    superpig

    Insert bacon, receive bugfix Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    3,795
    Correct; same as the Inspector.
     
  15. ffleurey

    ffleurey

    Joined:
    Apr 4, 2016
    Posts:
    1
    I wrote a little workaround:
    Code (CSharp):
    1. public class JsonHelper
    2. {
    3.     public static T[] getJsonArray<T>(string json)
    4.     {
    5.         string newJson = "{ \"array\": " + json + "}";
    6.         Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>> (newJson);
    7.         return wrapper.array;
    8.     }
    9.  
    10.     [Serializable]
    11.     private class Wrapper<T>
    12.     {
    13.         public T[] array;
    14.     }
    15. }
    You can now simple deserialize like this:
    Code (CSharp):
    1. YouObject[] objects = JsonHelper.getJsonArray<YouObject> (jsonString);
    Very surprising a such basic feature is not implemented...
     
    akasurreal, ina, Andrew915 and 8 others like this.
  16. jplanders

    jplanders

    Joined:
    Apr 8, 2016
    Posts:
    1
    This worked beautifully! Thanks ffleurey
     
  17. ImFromTheFuture

    ImFromTheFuture

    Joined:
    May 21, 2015
    Posts:
    25
    Hi, this helped a lot. Thank you!
     
  18. Dazzid

    Dazzid

    Joined:
    Apr 15, 2014
    Posts:
    61
    Hi,
    I'm trying this answer, but have doubts about how to properly set YouObject[]?
    Thanks for the help
     
    Krish-Vikram likes this.
  19. elektronische

    elektronische

    Joined:
    Nov 27, 2014
    Posts:
    43
    JSON Utility class doesn't support Array types or List yet?

    I'm trying something like this to use Lists and seems to work well, but i'm not sure if is a good implementation:

    Code (CSharp):
    1. [System.Serializable]
    2. public class PlayerStats{
    3.  
    4. public int life;
    5. public string name;
    6. public int energy;
    7. }
    Then,
    Code (CSharp):
    1. [System.Serializable]
    2. public class PlayerStatsList {
    3.  
    4.     public List <PlayerStats> playerStats;
    5. }
    Now, in the class that i wan't to access to the JSON File:
    Code (CSharp):
    1. public PlayerStatsList myPlayerStatsList = new PlayerStatsList();
    2.  
    3. JsonUtility.FromJsonOverwrite (jsonText, myPlayerStatsList);
    4.  
    With this, i have all the info loaded from the JSON file in the list myPlayerStatsList.playerStats.

    The JSON File must have the same structure that the PlayerStats class, like this:
    Code (CSharp):
    1. {
    2.     "PlayerStats": [
    3.         {
    4.             "life": "10",
    5.             "name": "Kratos",
    6.             "energy": 100
    7.         },
    8.         {
    9.             "life": "80",
    10.             "name": "Nathan",
    11.             "energy": 20
    12.         },
    13.         {
    14.             "life": "90",
    15.             "name": "Link",
    16.             "energy": 25
    17.         }
    18.     ]
    19. }
     
    Last edited: Aug 8, 2016
  20. Search

    Search

    Joined:
    Jul 24, 2014
    Posts:
    45
    Simple and clever, Thanks !
     
  21. MV10

    MV10

    Joined:
    Nov 6, 2015
    Posts:
    1,877
    If you use this free Unity-compatible fork of Newtonsoft's JSON.NET, then everything just works as you'd expect. There's a good reason even Microsoft recommends using this third-party solution rather than .NET's built-in options!

    https://github.com/SaladLab/Json.Net.Unity3D

    Code (csharp):
    1. PlayerStats[] statArray = JsonConvert.DeserializeObject<PlayerStats[]>(json);
     
  22. Krish-Vikram

    Krish-Vikram

    Joined:
    Aug 17, 2012
    Posts:
    6
    Is it working ?
    Its not Working for me :/
     
    VodkaFR likes this.
  23. rdvt

    rdvt

    Joined:
    Aug 23, 2014
    Posts:
    21
    Thanks, it work!!!!
     
  24. herosf2006

    herosf2006

    Joined:
    Nov 9, 2016
    Posts:
    4

    It's helpful, but how to make a file like ur file [PlayerStats].
     
  25. metaphysician

    metaphysician

    Joined:
    May 29, 2012
    Posts:
    97
    hey everyone! - i'm having a bit of trouble on the deserializing front. here's the basic array format in text file. note that my code doesn't contain the indents or line breaks - i assume that's not important? i'm breaking it up here so you can see the basic structure:
    Code (JavaScript):
    1.  
    2. {
    3. "SavedLayer":[
    4. {
    5. "layerName":"Layer_0",
    6. "instrumentNumber":0,
    7. "seqLength":7,
    8. "timeDivision":8,
    9. "gateTime":0.30000001192092898,
    10. "noteRowAssign":[30,42,44,46,47,59,63,80]
    11. },
    12. {"layerName":"Layer_1",
    13. "instrumentNumber":1,
    14. "seqLength":8,
    15. "timeDivision":16,
    16. "gateTime":0.30000001192092898,
    17. "noteRowAssign":[40,42,43,44,46,48,49,51]
    18. },
    19. ]
    20.  
    21. }
    i'm trying to retrieve it like this:

    Code (CSharp):
    1.  
    2. string AllTheData=File.ReadAllText(filename);
    3. SavedLayer[] data=JsonHelper.getJsonArray<SavedLayer>(AllTheData);
    SavedLayer is the basic class i created to store each object's data in JSON. it validates in JSON Lint as well. however if i try to get the first object in the array using this method, i get 'unexpected node type' and a Null Ref on the Debug.Log statement.

    any clue what i'm doing wrong here?
     
    Last edited: Nov 27, 2016
  26. superpig

    superpig

    Insert bacon, receive bugfix Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    3,795
    ffleurey's JsonHelper code expects the top-level array to be called 'array', not 'SavedLayer.'
     
  27. metaphysician

    metaphysician

    Joined:
    May 29, 2012
    Posts:
    97
    hmm - well looking at it after some sleep it actually looks like it wraps the '['and ']' that begin and end the array with '{ array:' and '}'. which technically means i don't have to bother as long as my array begins and ends with square brackets. but i'm still having a lot of trouble understanding the deserialization process. i went back to the Scripting API for retrieving JSON data (https://docs.unity3d.com/ScriptReference/JsonUtility.FromJson.html). i've given it a try, but my code is definitely not working. the main bit is here:

    Code (CSharp):
    1.     public static DataManager.SavedLayer readLayerJSON(string dataString)
    2.     {
    3.         string AllTheData = File.ReadAllText(DataManager.filenamePath());
    4.         allLayers = JsonHelper.getJsonArray<DataManager.SavedLayer>(AllTheData);
    5.  
    6.         for (int count=0; count <8; count++)
    7.         {
    8.             return JsonUtility.FromJson<DataManager.SavedLayer>(dataString);
    9.         }
    10.  
    11.     }
    i'm obviously getting confused about what all the data(aka AllTheData) is vs parsing out each individual JSON object within the data. is it possible to retrieve all data for all objects at once without having to loop? this code fails but all my fixes so far aren't doing the trick. i want to copy each Layer object's JSON data to each element of allLayers, which is an array of DataManager.SavedLayer classes. assistance appreciated!
     
  28. Artyom-Abgaryan

    Artyom-Abgaryan

    Joined:
    Jan 9, 2010
    Posts:
    126
    ADD THAT INTO DOCUMENTATION !!!!

    There is no mention about properties in docs. So you can save developers' time and Karma of unitech :D
     
    TaleOf4Gamers, bik3r014 and wendigo like this.
  29. Andrew915

    Andrew915

    Joined:
    Mar 4, 2017
    Posts:
    2

    It works like charm ,man (Y) hope it wouldn't fail in any case Thanku
     
  30. Sarudil

    Sarudil

    Joined:
    Mar 3, 2017
    Posts:
    6
  31. coderlaze

    coderlaze

    Joined:
    Sep 20, 2014
    Posts:
    1
  32. Mangiarotti

    Mangiarotti

    Joined:
    Jan 8, 2016
    Posts:
    1
    You're an HERO elektronische!
    I confirm this works just fine and using lists instead of arrays brings only advantages to me!

    This is how the official unity documentation should look like:

    JsonUtility

    class in UnityEngine

    Other Versions


    Description
    Utility functions for working with JSON data.
    YO FOLKS, arrays DO NOT work with this utility!!! Just use Lists and FromJsonOverwrite to store lists of data.


     
  33. halzate93

    halzate93

    Joined:
    Apr 24, 2013
    Posts:
    4
    Absolutely right^

    However, if you do need/want to use arrays and don't want to/can change the response from the server you could just wrap your json array inside an object. Then you can use the Wrapper<T> method discussed before.

    So if you have this:
    Code (JavaScript):
    1. [
    2.     {
    3.         "id": "1",
    4.         "name": "foo"
    5.     },
    6.     {
    7.         "id": "2",
    8.         "name": "bar"
    9.     },
    10.     {
    11.         "id": "3",
    12.         "name": "baz"
    13.     }
    14. ]
    You want to get something like this:
    Code (JavaScript):
    1. {
    2.     "items": [
    3.         {
    4.             "id": "1",
    5.             "name": "foo"
    6.         },
    7.         {
    8.             "id": "2",
    9.             "name": "bar"
    10.         },
    11.         {
    12.             "id": "3",
    13.             "name": "baz"
    14.         }
    15.     ]
    16. }
    Here's my updated JsonHelper.cs https://gist.github.com/halzate93/77e2011123b6af2541074e2a9edd5fc0
    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4.     public static class JsonHelper
    5.     {
    6.         public static T[] FromJson<T>(string jsonArray)
    7.         {
    8.             jsonArray = WrapArray (jsonArray);
    9.             return FromJsonWrapped<T> (jsonArray);
    10.         }
    11.  
    12.         public static T[] FromJsonWrapped<T> (string jsonObject)
    13.         {
    14.             Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(jsonObject);
    15.             return wrapper.items;
    16.         }
    17.  
    18.         private static string WrapArray (string jsonArray)
    19.         {
    20.             return "{ \"items\": " + jsonArray + "}";
    21.         }
    22.  
    23.         public static string ToJson<T>(T[] array)
    24.         {
    25.             Wrapper<T> wrapper = new Wrapper<T>();
    26.             wrapper.items = array;
    27.             return JsonUtility.ToJson(wrapper);
    28.         }
    29.  
    30.         public static string ToJson<T>(T[] array, bool prettyPrint)
    31.         {
    32.             Wrapper<T> wrapper = new Wrapper<T>();
    33.             wrapper.items = array;
    34.             return JsonUtility.ToJson(wrapper, prettyPrint);
    35.         }
    36.  
    37.         [Serializable]
    38.         private class Wrapper<T>
    39.         {
    40.             public T[] items;
    41.         }
    42.     }
    43.  
     
  34. Zhindetz

    Zhindetz

    Joined:
    Nov 13, 2014
    Posts:
    2
    Hi all, thank you for sharing the information.
    I use JavaScript, but did not find any useful example of how to use JsonUtility.FromJson in JavaScript.
    In case anyone is looking for how to deserialize (convert) JSON with array in Unity using JavaScript I've made an example:
    Code (JavaScript):
    1. // Unity data classses
    2. public class Ball { // this is required in both cases: single and array
    3.     public var size : float;
    4.     public var color : String;
    5.     public var weight : int;
    6. }
    7.  
    8. public class Balls { // this is required only in case of array
    9.     public var allBalls : Ball[];
    10. }
    11.  
    12. // Get JSON data
    13. var ballJson : String = '{"size":1,"color":"red","weight":2}';
    14.  
    15. // Instantiate data from JSON
    16. var oneBall : Ball = JsonUtility.FromJson.<Ball>(ballJson);
    17.  
    18. // Use the data
    19. Debug.Log('RED BALL:\nCOLOR: '+oneBall.color+'\nSIZE: '+oneBall.size+'\nWEIGHT: '+oneBall.weight);
    20.  
    21. // Get JSON data
    22. var ballsJson : String = '{"allBalls":[{"size":"1f","color":"red","weight":2},{"size":"1.2f","color":"blue","weight":3},{"size":0.9,"color":"green","weight":5}]}';
    23.  
    24. // Instantiate data from JSON with array
    25. var manyBalls : Balls = JsonUtility.FromJson.<Balls>(ballsJson);
    26.  
    27. // Use the data
    28. for (var i = 0; i < manyBalls.allBalls.length; i++) {
    29.     Debug.Log('#'+i+') BALL:\nCOLOR: '+manyBalls.allBalls[i].color+'\nSIZE: '+manyBalls.allBalls[i].size+'\nWEIGHT: '+manyBalls.allBalls[i].weight);
    30. }
    You can use JsonUtility.FromJson(ballJson, Ball) instead of JsonUtility.FromJson.<Ball>(ballJson) if you like.

    Result looks like:
    ScreenShot.PNG
     
    Last edited: Apr 25, 2017
    superpig likes this.
  35. Ali_Akbar_Montazeri

    Ali_Akbar_Montazeri

    Joined:
    Dec 6, 2014
    Posts:
    159
    hi @halzate93 thanks for your codes, but your FromJson function seems doesn't work for me. It gives me NullReferenceException.

    I have a simple code like below using your FromJson function :
    Code (CSharp):
    1. void Start () {
    2.         TextAsset data = Resources.Load("Creature") as TextAsset;
    3.         Debug.Log(data.name);
    4.         Debug.Log(data.text);
    5.         string dataText = data.ToString();
    6.         Creature[] creatures = JsonHelper.FromJson<Creature>(dataText);
    7.         Debug.Log(creatures.Length);
    8.         for (int i = 0; i < creatures.Length; i++) {
    9.             Debug.Log(creatures[i].Name);
    10.         }
    11.     }
    my json file structure is like this :
    Code (CSharp):
    1. [
    2.     {
    3.         "Name" : "ARC",
    4.         "Level" : "7",
    5.         "Stats" : [4,7]
    6.     },
    7.     {
    8.         "Name" : "ARS",
    9.         "Level" : "1",
    10.         "Stats" : [3,1]
    11.     }
    12. ]
     
  36. ImFromTheFuture

    ImFromTheFuture

    Joined:
    May 21, 2015
    Posts:
    25
    Read Post #15 and Post #33 in this thread. You need to use a wrapper around your json data to make it accessible.
     
  37. ItzChris92

    ItzChris92

    Joined:
    Apr 26, 2017
    Posts:
    190
    Slightly off topic. I've enjoyed reading through this thread, and it's helped me to successfully read and write toJson (using both lists and arrays). I don't suppose anyone here has hit the obstacle of derived classes not serializing correctly? All my data gets serialized as if it was the base type only
     
  38. pravinbudharap

    pravinbudharap

    Joined:
    Nov 23, 2015
    Posts:
    2
    {
    "test1": "first string",
    "test2": "second string",
    "test3" :
    [
    {
    "title" : "Red ",
    "image" : "Image Url"
    },
    {
    "title" : "Green ",
    "image" : "Image Url"
    },
    {
    "title" : "Blue ",
    "image" : "Image Url"
    },
    {
    "title" : "Yellow ",
    "image" : "Image Url"
    }
    ]
    }

    hi all i am confusing that i need to access the first value of the "buttons" array from this json and then pick up the first value which is "Red" so how can i access this value can you give me some detailing example because i am confused that how to access the array from json in unity i need to debugging the "title" object from the array.

    please can you help with some array objects in detaling .
     
  39. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,168
  40. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    267
    It is rather frustrating that this is supposedly on the list of thing to fix for like 2 years now. I am finding myself in the same boat here because I need to ingest data coming from a server that I have no control over, and all the data is returned in top level arrays :(
     
  41. ItzChris92

    ItzChris92

    Joined:
    Apr 26, 2017
    Posts:
    190
    I've recently started using JSON. NET which has overcome alot of the problems I've faced with JSONUtility, so it's definitely worth looking at
     
    Dustin-Horne likes this.
  42. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    267
    I've used it in the past. I prefer the speed and simplicity of Unity's built in solution. This is one of the few areas where it falls short.
     
  43. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,326
    I would agree with you there... it's a sledgehammer. Very capable and flexible, but I always suggest people check out JsonUtility first because if it works for their scenario it will be faster and less allocatey.
     
  44. HydroxTV

    HydroxTV

    Joined:
    Dec 21, 2015
    Posts:
    10
    I know its old, but I am STILL running into the same issue. Is this still not fixed after 2 years?!
     
  45. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    267
    I don't really think Unity considers it a bug, so they won't be fixing it. It is just a (extremely annoying) limitation of the system since they focused on speed. I don't really buy that considering how easy it is to work around it and still use the same system, but I'm pretty sure that is UT's stance on it :(

    I highly recommend using one of the "wrapper" scripts posted above. They work great.
     
  46. HydroxTV

    HydroxTV

    Joined:
    Dec 21, 2015
    Posts:
    10
    Giving:
    He said its "on the list to handle properly in the future". I mean hes still right with "in the future" but...seriously? 2years? I have used his solution in my project now and it works flawless. But seeing that they said "its on the list" and 2years later its...."still on the list?!" :D
     
  47. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,278
    It's a big list....https://unity3d.com/unity/roadmap
     
  48. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    267
    Good point. I did miss that note.
     
  49. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,326
    @superpig mentioned that they are working on some enhancements, including Dictionary support. Understandably, it's been awhile but keep in mind that this is the serializer that Unity uses internally and JsonUtility exposes that for use. As they add features, this is one area they have to be very careful not to break other things.