Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by NinjaMobin · Mar 07, 2017 at 01:21 PM · json

Parsing Nested Arrays with JsonUtility

I'm trying to parse this Json file with JsonUtility, the only problem is I cannot get the array of coordinates.

 {
 "features": [
 { "type": "Feature", "properties": { "id": 1.000000, "osm_id": -60.255, "name": "test", "type": "test" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 11.363926, 3.544844 ], [ 11.363489, 3.398182 ] ] ] } } ]
 }

This is my code:

 [System.Serializable]
 public class features{
     public string type;
     public properties properties;
     public geometry geometry;
 };
     
 [System.Serializable]
 public class PlayerStatsList {
     public List <features> features;
 };
 
 [System.Serializable]
 public class properties{    
     public int id;
     public int osm_id;
     public string name;
     public string type;
     }

 [System.Serializable]
 public class geometry{
     public string type;
     //some way to get coordinates
 }


I have tried some ways of accessing coordinates from other solutions like class of float array in a nested class, but it doesn't work, any help would be appreciated.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Bunny83 · Mar 07, 2017 at 02:20 PM

That's not possible with Unity's JsonUtility. You have to understand that the JsonUtility is not a general purpose JSON serializer / parser. It is build on top of Unity's serialization logic. Nested / jagged arrays or multidimensional arrays aren't supported by Unity's serialization system, so they can't be deserialized.

You basically have two options:

  • either build your serializable classes in a way that Unity can serialize and derive your JSON structure from that.

  • or if you want to use your own JSON structure, don't use JsonUtility and use a general purpose JSON parser.

One example would be my SimpleJSON parser. It's far from being perfect and doesn't deserialize to actual classes, but allow easy access to any information stored in a JSON file.

You can also easily add extension method to simplify the usage of certain Unity types. For example:

 public static class JSONNodeUnityExt
 {
     public static Vector4 ToVector4(this JSONNode aNode)
     {
         if (aNode is JSONArray)
             return new Vector4(aNode[0].AsFloat, aNode[1].AsFloat, aNode[2].AsFloat, aNode[3].AsFloat);
         else if (aNode is JSONClass)
             return new Vector4(aNode["x"].AsFloat, aNode["y"].AsFloat, aNode["z"].AsFloat, aNode["w"].AsFloat);
         return Vector4.zero;
     }
     public static Vector3 ToVector3(this JSONNode aNode)
     {
         if (aNode is JSONArray)
             return new Vector3(aNode[0].AsFloat, aNode[1].AsFloat, aNode[2].AsFloat);
         else if (aNode is JSONClass)
             return new Vector3(aNode["x"].AsFloat, aNode["y"].AsFloat, aNode["z"].AsFloat);
         return Vector3.zero;
     }
     public static Vector2 ToVector2(this JSONNode aNode)
     {
         if (aNode is JSONArray)
             return new Vector2(aNode[0].AsFloat, aNode[1].AsFloat);
         else if (aNode is JSONClass)
             return new Vector2(aNode["x"].AsFloat, aNode["y"].AsFloat);
         return Vector2.zero;
     }
 }

This allows easy conversion of a JSONNode into a Vector2/3/4. In your specific case you could do:

 var v1 = rootNode["features"][0]["geometry"]["coordinates"][0][0].ToVector2();
 var v2 = rootNode["features"][0]["geometry"]["coordinates"][0][1].ToVector2();

Of course you usually don't use the full path every time:

 var coords =  rootNode["features"][0]["geometry"]["coordinates"][0];
 for(int i = 0; i < coords.Count; i++)
 {
     var v = coords[i].ToVector2();
     ...
 }

Of course you can also make an extension method that converts a JSONNode into a list of coordinates:

 public static List<Vector2> ToVector2List(this JSONNode aNode)
 {
     if (aNode == null || !(aNode is JSONArray))
         return null; // or new List<Vector2>();
     var list = new List<Vector2>(aNode.Count);
     for(int i = 0; i < aNode.Count; i++)
     {
         var v = aNode[i].ToVector2();
         list.Add(v);
     }
     return list;
 }

Now you could simply do:

 List<Vector2> coords = rootNode["features"][0]["geometry"]["coordinates"][0].ToVector2List();

If you prefer arrays, just create an extension for that ^^.

Of course there are other JSON parsing solutions out there. LitJson is quite popular but has it's own restrictions.

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NinjaMobin · Mar 07, 2017 at 03:39 PM 0
Share

I'm glad you have replied to my post, Bunny83. SimpleJSON parser that you have written was the first thing I tried, but unfortunately I kept getting this error "NotImplementedException: null".

The files I am using are between 3-10$$anonymous$$B, and when I truncated one of the JSON files I was able to use your parser, but I need to parse the complete data, but it gives me the above error. Thanks a lot for your input.

avatar image NinjaMobin · Mar 08, 2017 at 12:43 PM 0
Share

I'll just divide my files into smaller files to be able to access it like this, SimpleJSON keeps throwing exceptions for large files. Thanks Bunny83.

avatar image Bunny83 NinjaMobin · Mar 08, 2017 at 02:16 PM 1
Share

No, it doesn't throw exceptions for large files ^^. The problem here is actually not my code but code that has been added by someone else (it's a wiki, you know ^^). Initially i did not "remember" the type of each json type and simply store it as string in a JSONData node. Of course when generating json back out of the node tree all values would have been strings, even when they were numbers, true, false or null.

The NotImplemented exception is thrown by the "Numberize" method that this guy added. He simply assumed everything that is not a string is either a number or a boolean value. Though he forget about the special value null. This null value is causing the exception. So your JSON file probably contains a null value.

$$anonymous$$y original version on github shouldn't have that problem. A quick in-place fix would be to add a case for null inside "Numberize"

 static JSONData Numberize(string token)
 {
     // [ .... ] 
     if (token == "null")
         return new JSONData("null");
     throw new NotImplementedException(token);
 }

I have actually changed a lot to my "personal" version. (I also finally renamed JSONClass to JSONObject ^^). Since it's not that hard to parse the different values up front i created seperate data nodes for the various types. If you want my latest version i can upload it after polishing it a bit ^^

avatar image NinjaMobin Bunny83 · Mar 08, 2017 at 03:14 PM 0
Share

I'll patch the SimpleJSON.cs and test it now. I'd be glad to use your latest version. Thank you very much Bunny83, much appreciated ^^

Show more comments
avatar image losingisfun · Mar 09, 2018 at 06:21 AM 0
Share

I feel the need to express how outrageous this failing is. A multidimensional array is very common, and this problem wastes a lot of a user's time.

avatar image Bunny83 losingisfun · Mar 09, 2018 at 07:58 AM 0
Share

It is not very common in the serialization domain of Unity since it's not supported by the serializer at all. As i said in this answer the JsonUtility is just a json equivalent of Unity's serializer. It is not meant to be a general purpose json parser. You simply expect that it can do things it wasn't designed for. The documentaion does mention those limitations


JSON on it's own doesn't have support for multidimensional arrays but only jagged / nested arrays. So even when you have a serializer that supports jagged arrays it probably won't support multidimensional arrays as they have to be rectangular. Jagged arrays are not required to be rectangular and therefore a proper mapping might not be possible.


I've actually written SimpleJSON before Unity implemented the JsonUtility. Personally i don't like the fact that i have to create a seperate class to read or write data. $$anonymous$$ost object mapper can easily be tripped over when anything changes on the structure. Reading the data into an dynamic tree structure is much more flexible imo.

avatar image
1

Answer by gjf · Mar 07, 2017 at 01:20 PM

something like:

 public Vector2[] coordinates;
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NinjaMobin · Mar 07, 2017 at 04:23 PM 0
Share

The Vector2 array returns some random values, I think the parser isn't functioning properly.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

What is the easiest json library to integrate with Unity? 12 Answers

JSON vs XML for Unity C# 1 Answer

convert Java code that can retrieve the url content to unity javascript 0 Answers

Split string : how to automatically remove " ? 0 Answers

How to write a TextAsset to disk 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges