Search Unity

JSON .NET for Unity

Discussion in 'Assets and Asset Store' started by Dustin-Horne, Sep 13, 2013.

  1. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
  2. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Quick update. JSON .NET is currently NOT working on WinRT. I'm working to rectify the issue but running into some snags that are taking longer than expected. It seems that the Unity Editor compiles against Mono first when building to the output folder. As a result, it complains about missing types, but when I shim them in, the editor works but fails on the final publish. I haven't figured out exactly why yet but I'm implementing workarounds. If WinRT is a must, there are compiled JSON.Net official versions which will work with WinRT and you can swap them in until I get the fixes in place.
     
  3. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I wanted to give another update on WinRT support. This has been particularly challenging because of the disconnect between Unity and Windows 8. Some of the interactions I haven't been able to completely get my head around. The editor will complain about enumerations that are missing for instance when I try to do a build. I shim them in for WinRT and the build process goes a bit further but then complains that they conflict with an existing type. There seems to be parts of the build process that are targeting different versions of the framework, one most likely Mono and the other Native.

    For these reasons it has not been possible to fully integrate WinRT support into the code package but I have a solution that I am working on. I am reconfiguring a WinRT build to remove the same unsupported dependencies as I did with the current iteration. I will be compiling and including it as a separate assembly which seems like the only way to get it working with Unity for Windows Store apps.

    All existing code files will be wrapped with:
    Code (csharp):
    1.  
    2. #if !UNITY_WINRT
    3. #endif
    4.  
    This will allow you target all of the existing platforms. When you build for WinRT you will need to bring in the assembly from the asset package and you'll need to remove it again if you go back to build for the other platforms. Since the source code files for other platforms will be wrapped in the conditional you will not get any conflicts, you won't have to remove the script files, and they will not be compiled when targeting WinRT so you won't incur any extra overhead.

    I hope to have these updates complete over the weekend and will be pushing then as a 1.2.4 version. 1.2.3 was submitted to the Asset Store one week ago today and is still pending review. Support for Windows Phone 8 was fixed in 1.2.3.
     
  4. Daveman

    Daveman

    Joined:
    Jun 12, 2013
    Posts:
    11
    Dustin, first of all I'd like to say thank you for all your excellent work creating this. Seriously awesome and extremely useful.

    Unfortunately I am having some iOS AoT issues with version 1.2.1. I've created a test program that reads just fine on Mac but crashes on iOS. Specifically I get this:

    Code (csharp):
    1.  
    2.  
    3. 2013-11-03 20:34:07.158 ProductName[5080:60b] -> registered mono modules 0x1450640
    4. -> applicationDidFinishLaunching()
    5. -> applicationDidBecomeActive()
    6. Mono path[0] = '/var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed'
    7. Mono config path = '/var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed'
    8. Renderer: PowerVR SGX 543
    9. Vendor:   Imagination Technologies
    10. Version:  OpenGL ES 2.0 IMGSGX543-97
    11. GL_OES_depth_texture GL_OES_depth24 GL_OES_element_index_uint GL_OES_fbo_render_mipmap GL_OES_mapbuffer GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_standard_derivatives GL_OES_texture_float GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_vertex_array_object GL_EXT_blend_minmax GL_EXT_color_buffer_half_float GL_EXT_debug_label GL_EXT_debug_marker GL_EXT_discard_framebuffer GL_EXT_draw_instanced GL_EXT_instanced_arrays GL_EXT_map_buffer_range GL_EXT_occlusion_query_boolean GL_EXT_pvrtc_sRGB GL_EXT_read_format_bgra GL_EXT_separate_shader_objects GL_EXT_shader_framebuffer_fetch GL_EXT_shader_texture_lod GL_EXT_shadow_samplers GL_EXT_sRGB GL_EXT_texture_filter_anisotropic GL_EXT_texture_rg GL_EXT_texture_storage GL_APPLE_copy_texture_levels GL_APPLE_framebuffer_multisample GL_APPLE_rgb_422 GL_APPLE_sync GL_APPLE_texture_format_BGRA8888 GL_APPLE_texture_max_level GL_IMG_read_format GL_IMG_texture_compression_pvrtc
    12. Creating OpenGLES2.0 graphics device
    13. Initialize engine version: 4.2.2f1 (54f0fc09defb)
    14. Begin MonoManager ReloadAssembly
    15. Platform assembly: /var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/UnityEngine.dll (this message is harmless)
    16. Loading /var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/UnityEngine.dll into Unity Child Domain
    17. Non platform assembly: /private/var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/Mono.Security.dll (this message is harmless)
    18. Non platform assembly: /private/var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/System.dll (this message is harmless)
    19. Platform assembly: /var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/Assembly-CSharp.dll (this message is harmless)
    20. Loading /var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/Assembly-CSharp.dll into Unity Child Domain
    21. Non platform assembly: /private/var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/System.Core.dll (this message is harmless)
    22. Non platform assembly: /private/var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/SampleClassLibrary.dll (this message is harmless)
    23. Non platform assembly: /private/var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/System.Xml.dll (this message is harmless)
    24. Platform assembly: /var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/SampleClassLibrary.dll (this message is harmless)
    25. Loading /var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Managed/SampleClassLibrary.dll into Unity Child Domain
    26. - Completed reload, in  0.090 seconds
    27. About to load TileInfo /var/mobile/Applications/A1AEFD83-9DB5-4ACA-9D4F-5F2B9743FF0D/ProductName.app/Data/Raw/tileInfo.json
    28.  
    29. (Filename: /Applications/buildAgent/work/ea95e74f6e5f192d/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 54)
    30.  
    31. The following line explodes on iOS
    32.  
    33. (Filename: /Applications/buildAgent/work/ea95e74f6e5f192d/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 54)
    34.  
    35. ExecutionEngineException: Attempting to JIT compile method 'Newtonsoft.Json.Utilities.CollectionWrapper`1<int>:.ctor (System.Collections.Generic.ICollection`1<int>)' while running with --aot-only.
    36.  
    37.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    38. Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    39.   at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    40.   at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    41.   at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0
    42.   at Newtonsoft.Json.Utilities.CollectionUtils+<CreateCollectionWrapper>c__AnonStorey14.<>m__2A (System.Type t, IList`1 a) [0x00000] in <filename unknown>:0
    43.   at Newtonsoft.Json.Utilities.ReflectionUtils.CreateGeneric (System.Type genericTypeDefinition, IList`1 innerTypes, System.Func`3 instanceCreator, System.Object[] args) [0x00000] in <filename unknown>:0
    44.   at Newtonsoft.Json.Utilities.CollectionUtils.CreateCollectionWrapper (System.Object list) [0x00000] in <filename unknown>:0
    45.   at Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList (System.Type listType, System.Action`2 populateList) [0x00000] in <filename unknown>:0
    46.   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateList (Newtonsoft.Json.JsonReader reader, System.String reference, Newtonsoft.Json.Serialization.JsonArrayContract contract) [0x00000] in <filename unknown>:0
    47.   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, System.Object existingValue, System.String reference) [0x00000] in <filename unknown>:0
    48.   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, System.Object existingValue) [0x00000] in <filename unknown>:0
    49.   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueProperty (Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonProperty property, System.Object target, Boolean gottenCurrentValue, System.Object currentValue) [0x00000] in <filename unknown>:0
    50.   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue (Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonReader reader, System.Object target) [0x00000] in <filename unknown>:0
    51.   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject (System.Object newObject, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, System.String id) [0x00000] in <filename unknown>:0
    52.  
    53. (Filename:  Line: -1)
    54.  
    when running this code (test program):

    Code (csharp):
    1.  
    2. using Newtonsoft.Json;
    3. using UnityEngine;
    4. using System;
    5. using System.Collections.Generic;
    6. using System.IO;
    7.  
    8. public class TestJSON : MonoBehaviour {
    9.  
    10.     // Update is called once per frame
    11.     bool read = false;
    12.     void Update() {
    13.         if (!read) {
    14.             read = true;
    15.             readTileInfo();
    16.         }
    17.     }
    18.  
    19.     public enum TTile {
    20.         Invalid,
    21.         Floor, Up, Down, Wall, //Breakable,
    22.         Wall_C,
    23.         Wall_N,
    24.         Wall_S, Wall_SN,
    25.         Wall_W, Wall_WN, Wall_WS, Wall_WSN,
    26.         Wall_E, Wall_EN, Wall_ES, Wall_ESN, Wall_EW, Wall_EWN, Wall_EWS, Wall_EWSN,
    27.         Shadow,
    28.         Door,
    29.         //Decorator,
    30.         Floor_entry,
    31.         Bridge, Bridge_NS, Bridge_EW,
    32.         Water,
    33.         Statue,
    34.         NumTiles
    35.     };
    36.  
    37.     public class Tile {
    38.         public Tile() { }
    39.         public Tile(TTile newType) { Type = (int)newType; Attributes = new HashSet<int/*TAttr*/>(); }
    40.         public int/*TTile*/ Type;
    41.         public string Name;
    42.         public HashSet<int/*TAttr*/> Attributes;
    43.         public string ToJson() {
    44.             return String.Format("{{'Type':'{0}','Attributes':{1},'Name':'{2}'}}",
    45.                 Type.ToString(), JsonConvert.SerializeObject(Attributes), Name);
    46.         }
    47.     }
    48.  
    49.     void readTileInfo() {
    50.         var filename = Path.Combine(Application.streamingAssetsPath, "tileInfo.json");
    51.         JsonSerializer serializer = new JsonSerializer();
    52.         Dictionary<string, Tile> AllTiles = new Dictionary<string, Tile>();
    53.         using (StreamReader sr = new StreamReader(filename))
    54.         using (JsonReader reader = new JsonTextReader(sr)) {
    55.             Debug.Log("About to load TileInfo " + filename);
    56.             Debug.Log("The following line explodes on iOS");
    57.             AllTiles = serializer.Deserialize<Dictionary<string, Tile>>(reader);
    58.             Debug.Log("Finished loading " + filename);
    59.         }
    60.     }
    61. }
    62.  
    from this JSON data (shortened because I had tons of data):

    Code (csharp):
    1.  
    2. {"world_0059":{"Type":4,"Name":"world_0059","Attributes":[]},"world_0060":{"Type":4,"Name":"world_0060","Attributes":[]}}
    3.  
    Any ideas? Hashset or dictionary a problem? This works perfectly with a native Mac build (e.g. Play in Editor).

    Thank you for looking at this.
     
    Last edited: Nov 4, 2013
  5. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    It should be an issue. I'll take a look at the CollectionWrapper and see if I can figure out why it's blowing up. I've asked the Asset Store to cancel my version 1.2.3 submission while I work on this and another WebPlayer issue that has been reported. Thanks for the repro. Also, if you could send me a private message with your Skype contact I'd appreciate it.

    Edit: It does seem like the HashSet<int> is causing the issue, not sure why yet.
     
    Last edited: Nov 4, 2013
  6. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Updates incoming!

    I didn't get my request in to the Asset Store in time and they published 1.2.3 :/ But I am going to be pushing version 1.2.5 very soon. I am waiting for one additional test to see if we can support HashSets for iOS. Here is the list of changes going into 1.2.5:

    1. Full WinRT Support (Finally!!! And without a separate DLL)

    2. Fix for Polymorphism in WebPlayer

    3. HashSet<T> support for iOS (hopefully - follow-up testing is happening today).

    The WinRT support is the biggest set of changes and took a lot of work. I am doing some cleanup, but essentially there are two components to building for a Windows Store app. The Unity Editor compiles against Mono but then targets the Windows SDK. Because of this, if I put in specific fixes for the Unity Editor, it would break in WinRT... but if I pulled them out it would break in the Editor.

    Due to this fact, WinRT now has a separate subfolder with an entirely different branch of Json .Net. There are no implementation changes. The primary Json .Net files are now all wrapped in:

    #if !UNITY_WINRT || UNITY_EDITOR

    and the new WinRT files are wrapped in:

    #if UNITY_WINRT !UNITY_EDITOR

    This results in an entirely separate set of Json code being built for RT than what is used in the editor and it fixes both platforms. Keep your eyes peeled and I'll let you know when the new version is test complete and has been submitted.
     
  7. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    JSON .NET Version 1.3.0 has just been submitted to the Asset Store and is pending approval! FastSpring purchasers will have an update available within the next 24 hours.

    New in this version:
    Full Support for WinRT
    Simplified Folder Structure
    Web Player bug fix for keyed collections
    Web Player bug fix for Polymorphism

    IMPORTANT! The old folder structure was very messy. If you are upgrading from an older version, the old root folder was Assets/DustinHorne. You need to delete this entire folder. The new Root folder is "JsonDotNet". The actual structure is as follows:

    /JsonDotNet/
    ...... /Examples/
    ....../Source/

    I've also included a better test scene in /JsonDotNet/Examples/Tests that allows you to run several common scenarios on different target platforms.
    Additionally, there the /JsonDotNet/Examples/Serialization folder contains several serialization example scripts showing you how to do basic, polymorphic and binary serialization.

    I'll post again when the update has been approved.

    Thanks!
     
  8. Joel-Santos

    Joel-Santos

    Joined:
    Feb 23, 2010
    Posts:
    121
    I almost forgot on commenting here. This product it's AMAZING.

    There was so many people looking for this on the forums and finally someone took the time and the knowledge to do it, and he did it well done :D

    I've bought this when it was launched and I am using it to try to implement a SignalR (that uses JSON serialization) client for Unity that works on the most platforms possible.

    At first I was happy with just iOS and Android, but now that the developer (who is also a great guy) took the time and ported it to Windows Phone 8 and Windows RT, which makes me very happy :p I've tested it on iOS/Android/WP8/Web and it works great on all of them, so the least I could do was to come here and tell you guys that if you are needing JSON serialization that works on most of the Unity platforms, look no further.

    And on top of all the code it's all visible. No DLLs.

    Once again, great work Dustin
     
  9. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Thanks Joel. ;) I'm going to jump on Skype and see if you're online so I can kick you the 1.3.0 version.
     
  10. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    I've yet to work with JSON, so my questions may be a bit basic, but I thought I'd ask anyways.

    I was wondering if this works with PlayerPrefs, and if so how would I save stuff/objects to PlayerPrefs?

    Also, does the BSON work with saving to PlayerPrefs as well, and if so how? Thanks.
     
  11. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yes you could use it with playerprefs by using SetString. As far as BSON, you'd have to convert it to a Base64 or something first because it's a byte array. In the Asset there is a sample that shows serializing to BSON and converting to a Base64 string, then deserializing the BSON back to an object.

    To use with player prefs, let's say you have the following class:

    Code (csharp):
    1.  
    2. public class Person
    3. {
    4.     public string FirstName { get; set; }
    5.     public string LastName { get; set; }
    6. }
    7.  
    So you would serialize and save to player prefs like this:

    Code (csharp):
    1.  
    2.  
    3. Person p = new Person();
    4. p.FirstName = Leroy;
    5. p.LastName = Jenkins;
    6.  
    7. string serializedPerson = JsonConvert.SerializeObject(p);
    8.  
    9. PlayerPrefs.SetString("Leroy", serializedPerson);
    10.  
    11.  
    And to get him back out:

    Code (csharp):
    1.  
    2.  
    3. Person p = JsonConvert.DeserializeObject<Person>(PlayerPrefs.GetString("Leroy"));
    4.  
    5.  

    If you go the BSON approach I would suggest creating your own saving mechanism to persist the data rather than use PlayerPrefs.
     
  12. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204

    Regarding the BSON approach, when you say "creating your own saving mechanism to persist the data rather than use PlayerPrefs" do you mean write to my own text file, or something else entirely?
     
  13. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Exactly, writing to your own file. In this case though, it would be binary instead of text. You would write the bytes directly to a file.
     
  14. ev3d

    ev3d

    Joined:
    Apr 19, 2013
    Posts:
    327
    I just purchased this in hopes of fixing a problem i have with serialization on IOS.. I am getting this only on IOS..


    MissingMethodException: Method not found: 'Default constructor not found...ctor() of System.ComponentModel.EnumConverter'.
    at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0
    at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0
    at System.ComponentModel.TypeDescriptor.GetConverter (System.Type type) [0x00000] in <filename unknown>:0
    at Newtonsoft.Json.Serialization.JsonTypeReflector.GetTypeConverter (System.Type type) [0x00000] in /Users/kris/EV3/Unity Source/EV3_Mac/Assets/DustinHorne/JsonDotNetUnity/Scripts/JsonNetUnity/Serialization/JsonTypeReflector.cs:173
    at Newtonsoft.Json.Utilities.ConvertUtils.GetConverter (System.Type t) [0x00000] in /Users/kris/EV3/Unity Source/EV3_Mac/Assets/DustinHorne/JsonDotNetUnity/Scripts/JsonNetUnity/Utilities/ConvertUtils.cs:457
    at Newtonsoft.Json.Serialization.DefaultContractResolver.CanConvertToString (System.Type type) [0x00000] in /Users/kris/EV3/Unity Source/EV3_Mac/Assets/DustinHorne/JsonDotNetUnity/Scripts/JsonNetUnity/Serialization/DefaultContractResolver.cs:630
    at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract (System.Type objectType) [0x0009d] in /Users/kris/EV3/Unity Source/EV3_Mac/Assets/DustinHorne/JsonDotNetUnity/Scripts/JsonNetUnity/Serialization/DefaultContractResolver.cs:617
    at Newtonsoft.Json.Utilities.ThreadSafeStore`2[System.Type,Newtonsoft.Json.Serialization.JsonContract].AddValue (System.Type key) [0x00000] in <filename unknown>:0
    at Newtonsoft.Json.Utilities.ThreadSafeStore`2[System.Type,Newtonsoft.Json.Serialization.JsonContract].Get (System.Type key) [0x00000] in <filename unknown>:0
    at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract (System.Type type) [0x00011] in /Users/kris/EV3/Unity Source/EV3_Mac/Assets/DustinHorne/JsonDotNetUnity/Scripts/JsonNetUnity/Serialization/DefaultContractResolver.cs:181
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.GetContractSafe (System.Object value) [0x00008] in /Users/kris/EV3/Unity Source/EV3_Mac/Assets/DustinHorne/JsonDotNetUnity/Scripts/JsonNetUnity/Serialization/JsonSerializerInternalWriter.cs:84
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContract collectionValueContract) [0x000fb] in /Users/kris/EV3/Unity Source/EV3_Mac/Assets/DustinHorne/JsonDotNetUnity/Scripts/JsonNetUnity/Serialization/JsonSerializerInternalWriter.cs:332
    UnityEngine.MonoBehaviour:StartCoroutine_Auto(IEnumerator)
    UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    UIPopups:CheckLogin() (at /Users/kris/EV3/Unity Source/EV3_Mac/Assets/Scripts/UI/UIPopups.cs:277)
     
  15. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Could you provide me a repro and the object you're attempting to serialize? System.ComponentModel.EnumConverter is a system type... looks like for some reason the iOS version is missing the default constructor so the type reflector can't create an instance of it.
     
  16. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    One more update as well. We've discovered what appears to be a Unity bug unless it was intended though I'm not sure why they would. When you target Windows Phone 8 everything will work fine in the editor, but when you do a Build, Unity adds the UNITY_WINRT conditional to the build. Once Version 1.3.0 is approved which added WinRT support, it breaks support for Windows Phone 8.

    Anyone who has purchased can send me their Invoice # and I will send you version 1.3.1 which fixes the build issue. I'm also filling a bug report with Unity.
     
  17. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    A bout of the flu in my household has set back my schedule but I'm back in action and version 1.3.1 has been submitted to the asset store. I was able to cancel version 1.3.0 so it would not introduce breaking changes for folks. Version 1.3.1 will be the next version to hit the store and contains all of the fixes above. I will post an update once it's approved.
     
  18. PfcGarcia

    PfcGarcia

    Joined:
    Aug 27, 2013
    Posts:
    17
    Hi Dustin,

    Object serialization works fine so far in Web Player but JObject.Parse fails even with simple string, like this:

    Code (csharp):
    1. string qq = "{\"game_config\":\"gfdgdfg\"}";
    2. JObject tt = JObject.Parse(qq);
    3.  
    In Windows build it's working ok. I'm using JSON.NET v.1.2.3 from Store. Maybe it is already fixed in newer versions?

    Thanks.
     
  19. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Ok, I'm assuming you're the one that just emailed me and asked for the latest version. I emailed it back to you. Any particular reason you're using the JObject directly instead of creating a class and serializing it?
     
  20. PfcGarcia

    PfcGarcia

    Joined:
    Aug 27, 2013
    Posts:
    17
    I need to obtain various types in the same JSON field, say there is JS object { Entity: { ... } } and Entity value can be mapped with multiple C# classes. But there should be only one wrapper class thus I need somehow to obtain underlying object in abstract form.
    Deserialize wrapper with Entity as object:

    Code (csharp):
    1. public class Wrapper
    2. {
    3.     public object Entity { get; set; }
    4.     public Wrapper() { }
    5. }
    6.  
    and then call Deserialize on sample string does not work.

    So the only solution I've found is to obtain Entity JSON stringified and then deserialize it. For this I tried to do the following:

    Code (csharp):
    1. T entity = JsonConvert.DeserializeObject<T>(JObject.Parse(wrapperJsonString)["Entity"].ToString());
    2.  
    and here JSON.NET failed with StackOverflowException:

    StackOverflowException: The requested operation caused a stack overflow.
    Newtonsoft.Json.Linq.JObject+JPropertKeyedCollection.InsertItem (Int32 index, Newtonsoft.Json.Linq.JToken item) (at Assets/JsonDotNet/Source/Linq/JObject.cs:81)
    System.Collections.ObjectModel.Collection`1[T].Insert (Int32 index, .T item) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs:107)
    Newtonsoft.Json.Linq.JObject+JPropertKeyedCollection.InsertItem (Int32 index, Newtonsoft.Json.Linq.JToken item) (at Assets/JsonDotNet/Source/Linq/JObject.cs:81)
    System.Collections.ObjectModel.Collection`1[T].Insert (Int32 index, .T item) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs:107)
    Newtonsoft.Json.Linq.JObject+JPropertKeyedCollection.InsertItem (Int32 index, Newtonsoft.Json.Linq.JToken item) (at Assets/JsonDotNet/Source/Linq/JObject.cs:81)
    System.Collections.ObjectModel.Collection`1[T].Insert (Int32 index, .T item) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs:107)
    Newtonsoft.Json.Linq.JObject+JPropertKeyedCollection.InsertItem (Int32 index, Newtonsoft.Json.Linq.JToken item) (at Assets/JsonDotNet/Source/Linq/JObject.cs:81)
    System.Collections.ObjectModel.Collection`1[T].Insert (Int32 index, .T item) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Collections.ObjectModel/Collection.cs:107)
    Newtonsoft.Json.Linq.JObject+JPropertKeyedCollection.InsertItem (Int32 index, Newtonsoft.Json.Linq.JToken item) (at Assets/JsonDotNet/Source/Linq/JObject.cs:81)


    If there is some elegant solution for this it will be much appreciated!

    Thanks.

    P.S. For now I just return Entity value as JSON stringified and then deserialize it.
     
    Last edited: Nov 20, 2013
  21. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I'll take a look. What you're saying makes sense. KeyedCollections have been troublesome. For some reason Unity implemented them differently for WebPlayer so the base class doesn't have the same signature as it does for other mono implementations and it has caused some major headaches. I'll build a repro project and figure out why it's tripping the error. It looks like it ended up with a circular method call somehow. I should have a fix for you by tomorrow.
     
  22. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Version 1.3.1 has been approved and is live on the asset store. I'm working on the JObject Parse issues and they will be fixed hopefully today as I'm back in the office.

    PfcGarcia -

    Instead of just storing the stringified value, since Entity is an "Object" just store whatever you need in it... then when you serialize, do it like this:

    Code (csharp):
    1.  
    2.  
    3. var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
    4. var serialized = JsonConvert.SerializeObject(myEntity, Formatting.None, settings);
    5.  
    6.  
    and to Deserialize it:

    Code (csharp):
    1.  
    2.  
    3. var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
    4. var myEntity = JsonConvert.DeserializeObject<Wrapper>(serialized, settings);
    5.  
    6.  
    You could also cache "settings" so you don't have to recreate it every time. What this will do is, even though your property is of type "Object", it will serialize it with the actual type of what you stuffed into it. That way you can use anything you want there.
     
  23. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    The issue with JObject has been fixed and will be included in the next release. The built in (not part of Json .Net) KeyedCollection class seems to have another issue in WebPlayer. In this case JPropertyKeyedCollection which inherits KeyedCollection was calling base.Insert(index, item) which causes a StackOverflowException. Changing it to instead use the base.InsertItem(index, item) method fixed the problem.
     
  24. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Would you generally recommend writing the JSON/BSON files to the Application.persistentDataPath directory from your own experiences with Unity, or is there somewhere else you'd recommend?
     
  25. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Sorry, I misread your question. :) Yes, use the persistentDataPath directory. You can write it elsewhere if you're just doing PC but you'll run into problems when targeting other devices like iPhone. Easiest is to just use the persistentDataPath. You may want to set a subfolder if you're targeting PC. You could do something like this:

    Code (csharp):
    1.  
    2. #if UNITY_IPHONE || UNITY_WINRT || UNITY_ANDROID || UNITY_WP8
    3.     var dataPath = Application.persistentDataPath;
    4. #else
    5.     var dataPath = System.IO.Path.Combine(Application.persistentDataPath, "subdirectoryname");
    6. #endif
    7.  
     
    Last edited: Nov 22, 2013
  26. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Thanks for the info. Also, regarding the serialization you explicitly say it's great for classes, but does this imply structs as well?

    Also, can you serialize static members?
     
  27. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yes and yes. It works fine for structs. Static members can be serialized as long as they're not constants ("const"). Private properties can also be serialized / deserialized as long as they are marked with the [Serializable] attribute. The only limitation at the moment is HashSet which doesn't play nice across platforms. I'm looking into whether there is a good solution for HashSet but we're limited by the version of Mono which points to .NET 3.5. HashSet in .NET versions below 4.0 do not implement the ISet<T> interface. The only thing that sets them apart from other base collections is that they implement ISerializable, but I can't automatically treat them as a HashSet because it would screw up custom collections marked as ISerializable. For now you can cast them to a Dictionary and they'll work just fine.
     
  28. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Ok, very informative. Finally, I couldn't quite find a way to serialize multiple objects then save them to the same file, and then properly read them back in to deserialize them using your plugin. Is there a suggestion you could make regarding this scenario?

    Edit:
    By multiple objects I meant two objects of different types/classes.
     
    Last edited: Nov 25, 2013
  29. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    You'd have to be a little more specific. If by multiple objects you're talking about instances of the same class you could put them in a List or Array and serialize that collection. You could create a container class to hold your different objects you're serializing. You could serialize each object to it's own file... or you could create your own format. If you're doing BSON for instance, you could serialize an object then see how many bytes it is. You could write into your file the number of bytes, followed by two "zero byte" bytes, then your data. Then follow that by two more zero bytes. Then the byte count of your next serialized object followed by two zero bytes, then the bytes of your next serialized object.

    So, when you read your file back in, the first thing you do is read until you find two "x00" entries. That first bit you read tells you how many bytes your serialized data is. Now you skip the two x00 entries and you read that number of bytes. Then deserialize that into your object. The "x00x00" are basically just delimiters that show where the actual serialized object data starts and stops. That's just an example... you could make that as complex or simple as you'd like and even store additional metadata along with your serialized data.
     
  30. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    By multiple objects I meant two objects of different types/classes. It sounds like "You could create a container class to hold your different objects you're serializing" seems like the quickest method to implement. Thanks.
     
    Last edited: Nov 25, 2013
  31. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yeah. I would recommend creating an object that represents your scenario. So you may create a "SaveGame" class that stores everything you want to save. Then serialize it.
     
  32. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    I've tried to serialize classes with non-const static members and so far, the class only serializes the non-static members. Are there any settings or suggestions for this?
     
  33. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Sorry, I had to think about that and I realized I told you incorrectly before. Static members cannot be serialized. That is because they are not actually part of any class instance. If you have classes with static members and have values set to them, you'll need to store those values elsewhere.

    As an example, let's say you have the following:

    Code (csharp):
    1.  
    2. public class StaticClassMember
    3. {
    4.     public string Foo { get; set; }
    5.  
    6.     public static int Bar { get; set; }
    7. }
    8.  
    Now you do this:

    Code (csharp):
    1.  
    2. var obj = new StaticClassMember();
    3.  
    "Foo" is part of obj because it's an instance variable. "Bar" however is static... it is not actually a member of "obj" so it won't be serialized. You don't set it by saying:

    Code (csharp):
    1.  
    2.  obj.Bar = 5;
    3.  
    You'd have to instead use:

    Code (csharp):
    1.  
    2. StaticClassMember.Bar = 5;
    3.  
     
  34. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    Thanks for all the help and information. Your plugin really saved us a lot of time and struggle. Looks like everything's working the way we need it to.
     
  35. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Great! Glad to hear it. If you have any other questions, feel free to reach out to me.
     
  36. vicenterusso

    vicenterusso

    Joined:
    Jan 8, 2013
    Posts:
    130
    Does it support List of Lists, Generics, etc ?
     
  37. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yes it does.
     
  38. Felix-Schlitter

    Felix-Schlitter

    Joined:
    Sep 30, 2013
    Posts:
    8
    This line

    is giving me a hard time. The function "GetUnderlyingType does not exist?

    Edit: And just after posting, I found the deviant. Soomla has a class called "Nullable". So I added the "System." prefix to the applicable lines... Maybe helpful to others
     
    Last edited: Nov 28, 2013
  39. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Glad you found it... I was just about to ask what platform as it shouldn't be causing an issue. What is Soomla? Sounds to me like Soomla created the "Nullable" type in the global namespace (not a good idea). Because they did that, my library couldn't resolve the correct version as Nullable is a system type that exists in the System namespace. That would be a good note to drop to the Soomla folks as they shouldn't be creating conflicting type names in the global namespace.
     
  40. Felix-Schlitter

    Felix-Schlitter

    Joined:
    Sep 30, 2013
    Posts:
    8
    That's true, I might just do that. Well, I am having another issue now, I quote the output:

    What I can make of it is that you might be using a value type as key in a dictionary or something?
     
  41. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Cool Asset,

    I'm working on a project that requires quite a bit of data and performance is a big issue.

    Do you have performance metrics of this package on various unity platforms ?

    Cheers.
     
  42. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Could you provide some kind of repro code? Also, what Unity version and what Platform? Is it only on the "device" or does it happen in the editor?
     
  43. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Thanks! I really don't have any performance metrics. As far as speed of serialization and deserialization, it does make use of some type caching and is pretty fast but it's all going to depend on what you're serializing and deserializing.
     
  44. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    A simple test case:

    Let's say 1000 GameObject, each with a unique 10k mesh, 10k mesh collider.

    What would be the serializing/deserializing performance on various platforms.
     
  45. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    How often are you serializing and deserializing? Every frame? Once per game? If you could write up a test case and tell me what platform you want it tested on I could do it for you.
     
  46. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    I'm mainly interested performance on Mobile (Android,IOS) .

    I would be serializing/deserializing a few hundred times per game.

    If you are going to make the test, then it's easy to run the test at various params to get a better picture of the performance of this package.

    Do it for every frame and see what happens -- put it through the test.

    Cheers.
     
  47. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    If you supply me with the code (what you're serializing and how frequently) I can implement it... but I can't just guess at what you're trying to do. There are too many variables. All I would do is create some huge arrays and serialize / deserialize them over and over. So again, if you have some specific test code you want to provide me I can implement it.
     
  48. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    I don't have specific code at the moment, perhaps making some huge arrays would be a good place to start.
    This will at least give some metrics as to the performance of the package.
     
  49. Felix-Schlitter

    Felix-Schlitter

    Joined:
    Sep 30, 2013
    Posts:
    8
    In regards to the error I reported in my previous post in this thread, this is the full stack trace: http://pastebin.com/rquQHxJY

    Thanks for looking into this
     
  50. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Thanks. Could you please answer my other questions:

    1. What platform are you targeting?
    2. Does it happen in the editor?
    3. Does it happen on the device?
    4. Does it happen on multiple platforms?

    Also, please provide me with the reproduction code so I can see what you're deserializing. I need the class and the raw JSON if you're deserializing.