Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Disabling JsonUtility Serialization Depth Limit of 10

Discussion in 'Scripting' started by nickhudson2244, Jun 4, 2023.

  1. nickhudson2244

    nickhudson2244

    Joined:
    Mar 18, 2019
    Posts:
    15
    Our project serialization can at times serialize at a depth greater than 10 which triggers the JsonUtility depth limit. Which halts serialization at 10. Our save files are often greater than 10 in depth. There isn't really a way around this.

    We would like to stick with JsonUtility over Newtonsoft or Microsoft as JsonUtility is able to directly serialize unity objects. As well as some other reasons.

    Our solution at the moment is to use https://docs.unity3d.com/ScriptReference/SerializeReference.html which basically breaks out of the large serialization depth by assigning RIDs in the JSON that references the actual block of JSON. Although this works fine, it adds an extra level of complexity to the JSON file which could cause issues in the future with manual JSON parsing for things like save file conversion.

    Any ideas? Thanks!
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,606
    Can't disable it. It's there for a reason to stop Unity from going infinite because its default serialisation is all inlined/as values.

    The solution is to just use SerializeReference, or use a proper serialiser over the fragile JsonUtility.
     
    Bunny83 likes this.
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,913
    There's currently no way around that. Unity's JsonUtility is the fastest out of all solutions as it's implemented in native code and has several restrictions which makes it fast. The depth limit of 10 (it used to be 7) is just their solution to break out of potential infinite serialization loops. Checking for circular references is expensive while counting the depth in the recursive serialization function is cheap. It's very unlikely that Unity will change their serializer.

    As you said, the relatively new SerializeReference could solve the issue, though as already stated in the documentation it comes with a performance penalty and the more complex structure. However it provides more features.

    If you want to have more control over the serialization, you would have to roll your own or use a more general serializer. What kind of "Unity objects" do we actually talk about? Do you mean Unity's struct types such as Vector3? Or do you mean something else? UnityEngine.Object derived reference types would not really serialize properly as it just serializes the instance ID which is not guaranteed to stay constant between sessions and updates.

    The Newtonsoft serializer supports a list of custom converters. When you use this overload you can supply an array of custom converters. It has tons of other customizations such as custom SerializationBinders which can store type information for a certain type so polymorphic serialization would be possible.

    Note that the examples given in the documentation are not really sophisticated, but you should get the idea. So you can create a converter for things like Vector3 and decide what data you actually want to store. Maybe an object with x, y and z keys or an array that just contains 3 floats?! A converter can also store it's own type information to support polymorphism for types which may not be serializable. It's up to the converter to convert the necessary data to some kind of json and to recreate / "relink" that object on deserialization.
     
    AngryProgrammer and spiney199 like this.