Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

How to load an array with JsonUtility?

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

  1. HinxLai

    HinxLai

    Joined:
    Dec 31, 2017
    Posts:
    4
    Instead of LitJson or miniJson. JsonUtility dosen't support array. or make json yourself.
     
  2. AvenBeater

    AvenBeater

    Joined:
    Jan 25, 2014
    Posts:
    2
    All of this methods doesn't work.
     
    Zante likes this.
  3. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
  4. GuruJeya14

    GuruJeya14

    Joined:
    Jun 29, 2017
    Posts:
    9
    It
    Thanks a lot! Works perfectly!!
     
    lena_unity458 likes this.
  5. MSOTech

    MSOTech

    Joined:
    Oct 12, 2013
    Posts:
    3
    I was having an issue deserializing JSON file. It turns out, my class was inheriting from MonoBehaviour. When I removed it, everything worked fine.

    So, I changed it from this:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. [System.Serializable]
    5. public class QuestionList : MonoBehaviour {
    6.     public List<Question> questionList;
    7. }
    To this, and this one worked:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. [System.Serializable]
    5. public class QuestionList {
    6.     public List<Question> questionList;
    7. }
     
  6. Cuicui_Studios

    Cuicui_Studios

    Joined:
    May 3, 2014
    Posts:
    66
    Hi there!
    So, we've spent countless hours with this json and list related issue and right now we can't see neither the trees, the forest, the mountains or the damn partridge on the friggin pear tree.
    We've got this json file with a couple of lists and we're using these classes to map the json to objects:

    Code (CSharp):
    1. using System.Collections.Generic;
    2.  
    3. [System.Serializable]
    4. public class ClassA
    5. {
    6.     public int myInt;
    7.     public string myStringOne;
    8.     public string myStringTwo;
    9. }
    10.  
    11. [System.Serializable]
    12. public class ClassB
    13. {
    14.     public int myInt;
    15.     public string myString;
    16.     public List<int> myIntList;
    17. }
    18.  
    19. [System.Serializable]
    20. public class FullOfLists
    21. {
    22.     public List<ClassA> listOne;
    23.     public List<ClassB> listTwo;
    24. }
    And the json we're trying to parse looks like this one:

    Code (CSharp):
    1. {
    2.     "fullOfLists" :
    3.     {
    4.         "listOne":
    5.         [
    6.             {
    7.                 "myInt": 1,
    8.                 "myStringOne": "Cool first string",
    9.                 "myStringTwo": "Cool second string"
    10.             },
    11.             {
    12.                 "myInt": 23,
    13.                 "myStringOne": "Another cool first string",
    14.                 "myStringTwo": "Another cool second string"
    15.             },
    16.             {
    17.                 "myInt": 666,
    18.                 "myStringOne": "Yet another cool first string",
    19.                 "myStringTwo": "Yet another cool second string"
    20.             }
    21.         ],
    22.         "listTwo":
    23.         [
    24.             {
    25.                 "myInt": 1444,
    26.                 "myString": "Such a cool string",
    27.                 "myIntList": [2,7,14]
    28.             },
    29.             {
    30.                 "myInt": 3144,
    31.                 "myString": "Such a way cooler string",
    32.                 "myIntList": [4,14,31]
    33.             }
    34.         ]
    35.     }
    36. }
    The thing is whenever we do
    Code (CSharp):
    1. FullOfLists myFullObject = JsonUtility.FromJson<FullOfLists>(thousandTimesCheckedCorrectJson);
    When the myFullObject is created, it contains the two lists (named correctly), but empty. Is there anything that we are missing?
    We've been browsing unity answers, forums and google, and there's no amount of coffee in the world that can make us see our code as incorret. Any advice?
    Thanks in advance, guys.
     
  7. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,861
    Try initializing the lists. public List<int> whatever = new List<int>.
     
  8. Cuicui_Studios

    Cuicui_Studios

    Joined:
    May 3, 2014
    Posts:
    66
    Thanks for the suggestions, but since it was a matter of loading static data we decided to switch to using ScriptableObject instead. It's weird tho, because we've successfully used JsonUtils.FromJson in other projects, but as of this little project, there's no available time to keep investigating the issue. Thanks again!
     
  9. Eco-Editor

    Eco-Editor

    Joined:
    Jun 29, 2016
    Posts:
    66
    Hello all,

    I'm using a method suggested above: JsonHelper class
    My goal is to save an item when choice submitted and load all items when asked.
    Have a struct:
    Code (CSharp):
    1.    
    2. [System.Serializable]
    3.     public class PlayerInput
    4.     {
    5.         public string itemName = "";
    6.         public string itemTag = "";
    7.     }
    have the DataManager class:
    Code (CSharp):
    1.  public class DataManager : MonoBehaviour
    2.     {
    3.         public PlayerInput playerInputData;
    4.         private string file = "playerInput.txt";
    5.         public void Save()
    6.         {
    7.             string[] data = new string[] { playerInputData.itemName, playerInputData.itemTag };
    8.             string json = ArrayToJson(data);
    9.             WriteToFile(file, json);
    10.         }
    11.  
    12.         public static string ArrayToJson<T>(T[] array)
    13.         {
    14.             Wrapper<T> wrapper = new Wrapper<T> { array = array };
    15.             string json = JsonUtility.ToJson(wrapper);
    16.             return json;
    17.         }
    18.  
    19.         [ContextMenu("Load Data")]
    20.         public void Load()
    21.         {
    22.             string json = ReadFromFile(file);
    23.  
    24.             PlayerInput [] items = JsonHelper.GetJsonArray<PlayerInput>(json);
    25.  
    26.             foreach (PlayerInput pi in items)
    27.             {
    28.                 print("item tags is: " + pi.itemTag + "item name is: " + pi.itemName);
    29.             }
    30.             // JsonUtility.FromJsonOverwrite(json, playerInputData);
    31.         }
    32.  
    33.         private void WriteToFile(string fileName, string json)
    34.         {
    35.             string folderPath = GetFilePath(fileName);
    36.             FileStream fileStream = new FileStream(folderPath, FileMode.Append);
    37.             using (StreamWriter writer = new StreamWriter(fileStream))
    38.             {
    39.                 writer.Write(json);
    40.             }
    41.         }
    42.  
    43.         private string ReadFromFile(string fileName)
    44.         {
    45.             string folderPath = GetFilePath(fileName);
    46.             if (File.Exists(folderPath))
    47.             {
    48.                 using (StreamReader reader = new StreamReader(folderPath))
    49.                 {
    50.                     string json = reader.ReadToEnd();
    51.                     return json;
    52.                 }
    53.             }
    54.             else
    55.             {
    56.                 Debug.LogWarning("File not found!");
    57.             }
    58.             return "";
    59.         }
    60.  
    61.         private string GetFilePath(string fileName)
    62.         {
    63.             return Application.persistentDataPath + "/" + fileName;
    64.         }
    65.  
    66.  
    67.     }
    Have the Json output:
    Code (CSharp):
    1. {"array":["q","weapon"]}{"array":["w","stamina"]}
    I see the objects in the Json file are not sapareted by coma or } and I get an error in unity:
    ArgumentException: JSON parse error: Missing a comma or '}' after an object member.

    What to do so multiple entries will build a valid json file to parse.
    my goal is to save multiple times but to load the json output all at once.
     
  10. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,805
    ...make that 5 years :D.
     
    dan_ginovker and ZenUnity like this.
  11. arutyunef

    arutyunef

    Joined:
    May 30, 2019
    Posts:
    3
    Properties aren't serializable? They are, if they are auto-properties. Use this: [field: SerializeField]
     
  12. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,805
  13. MrG

    MrG

    Joined:
    Oct 6, 2012
    Posts:
    355
    4.25 years later, this is still broken.
     
  14. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Kurt-Dekker likes this.
  15. MrG

    MrG

    Joined:
    Oct 6, 2012
    Posts:
    355
    dan_ginovker likes this.
  16. Zillaxwafer

    Zillaxwafer

    Joined:
    Dec 23, 2016
    Posts:
    1
    Bit of a necro, but I ended adding a simple generic class with variable type, like so:

    Code (CSharp):
    1. [Serializable]
    2. public class ObjectList<T>
    3. {
    4.     public List<T> data;
    5. }
    Then simply used that in place of the "Type" requirement for JsonUtil, filling in the type I wanted for T and then putting ".data" on the end to return the data as the correct list type.

    Code (CSharp):
    1.  GuildList = JsonUtility.FromJson<ObjectList<Guild>>(asset.text).data;
    This of course means in all of my json files, regardless of type, I have to put "data" as a list variable like so... but ended up feeling really clean and flexible.

    Code (JavaScript):
    1. {
    2.     "data":
    3.         [
    4.             {
    5.                 "guildName": "Guardians of Agamar",
    6.                 "virtue": 1  
    7.             },
    8.             {
    9.                 "guildName": "Test Guild",
    10.                 "virtue": 2  
    11.             }
    12.         ]
    13. }
    I'm sure there's probably some clever way to make it so my ObjectList<T> class can be implicitly converted rather than explicitly accessing .data, but I'm not sure the extra lines of code are worth the trouble.
     
  17. dryctnath

    dryctnath

    Joined:
    Aug 13, 2020
    Posts:
    1
    I really liked this solution, I modified it to add a static method that returns the data property like so:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3.  
    4. [System.Serializable]
    5. public class ListUtility<T>
    6. {
    7.     public List<T> data;
    8.  
    9.     public static List<T> CreateFromJson(string jsonString)
    10.     {
    11.         return JsonUtility.FromJson<ListUtility<T>>(jsonString).data;
    12.     }
    13. }
    Now I can use as follows:
    Code (CSharp):
    1. var jsonTextFile = Resources.Load<TextAsset>("WallSequence");
    2.         List<WallConfig> wallConfigs = ListUtility<WallConfig>.CreateFromJson(jsonTextFile.ToString());
     
  18. Miscellaneous

    Miscellaneous

    Joined:
    Sep 24, 2013
    Posts:
    51
    Half a decade later, any plans for supporting Arrays [possible also Dictionaries and Lists]?
     
  19. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    33,727
    I'm gonna go out on a limb and just say "no," and since Newtonsoft JSON .NET is free on the asset store (and someone else posted some other forks of it above), and since our company uses it in 100% of our Unity games and blast TONS of randomly-shaped data through it without any issues (ever!), just go with that. Not worth tinkering around with Fisher Price JSON built in. Your time is worth more than that.
     
    auwilliams and a436t4ataf like this.
  20. auwilliams

    auwilliams

    Joined:
    Nov 1, 2022
    Posts:
    2
    7 years later and we still can't natively handle arrays and lists? Really guys?
     
  21. auwilliams

    auwilliams

    Joined:
    Nov 1, 2022
    Posts:
    2
    I would agree with this if Unity didn't just break the most popular JSON package with namespace collisions. We found a separate library we are happy with - but happy with Unity, not so much.
     
  22. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,149
    First if all it does handle lists and arrays, just not as a root element or directly nested arrays. EVERY json parser / framework does choose some kind of restrictions because the json standard does not put a limit on the precision of numbers for example. However most frameworks only support double values, some may only support float values, others only int values. Unity's JsonUtility is just an extension of the built-in serialization system and it's one of the fastest you can get in Unity (there has been several benchmarks on that topic). So either you can adjust your requirements to match the limitations, or you use a different framework if you really need support for a specific json feature.

    I do agree that in terms of package managing and dependency handling Unity's approach is lacking a bit. Though you will find such issues in other systems and engines as well. If every package would ship their own seperate package, your application could end up with the same framework being included several times which would be crazy. C# in general usually has way less issues and requires way less configutation compared to a C++ application when you use tons of libraries which have cross-dependencies.
     
  23. CrandellWS

    CrandellWS

    Joined:
    Oct 31, 2015
    Posts:
    177