25

I've got some data I need to serialize/deserialize, but JsonUtility is just not doing what it's supposed to. Here's the objects I'm working with:

public class SpriteData {
    public string sprite_name;
    public Vector2 sprite_size;
    public List<Vector2> subimage;
}

public class SpriteDataCollection
{
    public SpriteData[] sprites;
}

If I create a SpriteDataCollection, and attempt to serialize it with JsonUtility, I just get an empty object {}. Here's how it's being built:

            SpriteData data = new SpriteData();
            data.sprite_name = "idle";
            data.sprite_size = new Vector2(64.0f, 64.0f);
            data.subimage = new List<Vector2> { new Vector2(0.0f, 0.0f) };

            SpriteDataCollection col = new SpriteDataCollection();
            col.sprites = new SpriteData[] { data };

            Debug.Log(JsonUtility.ToJson(col));

The debug log only prints "{}". Why isn't it serializing anything? I've tested it out, and serializing a single SpriteData does exactly what it's supposed to do, but it won't work in the SpriteDataCollection.

Matthew Fournier
  • 1,077
  • 2
  • 17
  • 32

5 Answers5

45

There are 4 known possible reasons why you may get empty Json in Unity.

1.Not including [Serializable]. You get empty json if you don't include this.

2.Using property (get/set) as your variable. JsonUtility does not support this.

3.Trying to serializing a collection other than List.

4.Your json is multi array which JsonUtility does not support and needs a wrapper to work.

The problem looks like #1. You are missing [Serializable] on the the classes. You must add using System; in order to use that.

[Serializable]
public class SpriteData {
    public string sprite_name;
    public Vector2 sprite_size;
    public List<Vector2> subimage;
}

and

[Serializable]
public class SpriteDataCollection
{
    public SpriteData[] sprites;
}

5.Like the example, given above in the SpriteData class, the variable must be a public variable. If it is a private variable, add [SerializeField] at the top of it.

[Serializable]
public class SpriteDataCollection
{
    [SerializeField]
    private SpriteData[] sprites;
}

If still not working then your json is probably invalid. Read "4.TROUBLESHOOTING JsonUtility" from the answer in the "Serialize and Deserialize Json and Json Array in Unity" post. That should give you inside on how to fix this.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • 1
    I figured it was some sort of magic tag or something I had to do, thanks. It's working as intended now. – Matthew Fournier Jan 22 '17 at 03:54
  • 1
    I just ran into this and for me the problem was 5. my fields weren't marked as public. I know it's in the rules, just slipped my mind. – Kyle Postlewait Sep 28 '17 at 14:24
  • @KylePostlewait It's a common sense thing that if it is private it won't be serialized. Although, you can put `[SerializeField]` on top of the private field to make it serialize. – Programmer Sep 28 '17 at 14:27
  • Well 1 2 3 and 4 are pretty common sense too, I just thought I'd add it for completion as it was the first google result for my bumble. – Kyle Postlewait Sep 28 '17 at 14:51
  • @KylePostlewait The example from #4 uses `public` for everything but I modified the answer to include that. – Programmer Sep 28 '17 at 15:07
  • #2 worked for me. @Programmer once again my friend you are a god damn hero. – JoeyL Feb 15 '18 at 05:07
  • Much Thanks @Programmer. I was stuck because I didn't use List, used I list instead. – Vipin Verma Jul 11 '18 at 02:24
  • It won't serialize a List<> as the top level. You have to wrap it in a class with the [Serializable] tag – shieldgenerator7 Sep 24 '20 at 21:36
  • What if the List doesn't serialize but each individual MyObject does??? – pete Feb 01 '22 at 19:42
  • Responding to my previous comment, List will never serialize correctly when just printed by itself for debugging (it has to be in another class which is serializable). Also List of abstract class can't be serialized, and List of ParentClass containing ChildClass will only have ParentClass info when serialized. I have written about it in https://stackoverflow.com/questions/70947100/serialize-list-of-subclasses-not-working-in-jsonutility-in-unity/70947465#70947465 – pete Feb 01 '22 at 21:02
2

I know this post is old.. However, I recently had a similar problem to the question here. To clarify...

Using JsonUtility, if you have a List of a "serializable" class, JsonUtility will return an Empty response.

[Serializable]
public class SomeSerializableClass
{
     public SomeSerializableClassB instance = new();
}

[Serializable]
public class SomeSerializableClassB
{
     public int x = 123;
}

public class Something{
    public List<SomeSerializableClass> collection = new();

    public string GetJson()
    {
         return JsonUtility.ToJson(collection);
    }
}

GetJson() here will return nothing. Instead, wrap the List collection into another class, then it will serialize and convert correctly.

[Serializable]
public class SomeSerializableClassList
{
    public List<SomeSerializableClass> instances = new();
}

[Serializable]
public class SomeSerializableClass
{
     public SomeSerializableClassB instance = new();
}

[Serializable]
public class SomeSerializableClassB
{
     public int x = 123;
}

public class Something{
    public SomeSerializableClassList collection = new();

    public string GetJson()
    {
         return JsonUtility.ToJson(collection);
    }
}

Its difficult to comprehend why this doesn't work when you read "Lists are supported". Maybe someone smarter than me can explain...

1

One other cause Programmer didn't mention but is a big stickler:

[Serializable]
public struct MyObject
{
    public string someField;
}

[Serializable]
public class MyCollection
{
    public readonly List<MyObject> myObjects = new List<MyObject>();
    //     ^-- BAD
}

A list won't serialize if it is using readonly. E.g.

MyCollection collection = new MyCollection();
collection.myObjects.Add(new MyObject {someField = "Test"});
string json = JsonUtility.ToJson(collection);
// {}
Yes Barry
  • 9,514
  • 5
  • 50
  • 69
1

I fixed that by using Newtonsoft instead of JsonUtility as a converter.

here is an example

//here we will serialise or deserialize the data

public void SaveData
{

        List<Model> models = new List<Model>();
        //just adding some data
        models.Add(new Model { playerHealth = 10, saveTime = DateTime.Now, strength = 50 });

        //here pasing the data that are stoed on that variable into a json format
        string jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(models);
        Debug.Log(jsonText);
}

//this is the model

public class Model
{
    public DateTime saveTime;

    public int playerHealth;

    public int strength;

}

here are result enter image description here

Game dev
  • 296
  • 2
  • 17
0

Unity3D has an old-fashioned Json library. You can use the Newtonsoft.Json, a standard JSON library in .NET ecosystem. However, it doesn't support Unity3D and you need to get the specialized package for Unity3D. You can get it from its Github or from the Unity Asset Store.

using Newtonsoft.Json;
    ...
    ...

The_Object the_object = new The_Object(...);

....

string jsonString = JsonConvert.SerializeObject(the_object);

The_Oobject deserialized_object = JsonConvert.DeserializeObject<The_Object>(jsonString);

Please note that SerializableAttribute should be applied on The_Object class and any used object type inside it. Also, you have to indicate variables that you want to parse by json as public. For example:

[Serializable]
class first_class
{
    public second_class sceond = new second_class();
    public System.Collections.Generic.List<List<third_class>> third_nested_list;
    //....
}
[Serializable]
class second_class
{
    public third_class third = new third_class();
    //....
}
[Serializable]
class third_class
{
    public string name;

    //....
}
  • This answer is based on my working code. I wonder why did you vote down? – Payam Jome Yazdian Aug 31 '21 at 05:53
  • I'm not sure why you were voted down, and am sorry you had an unfriendly StackOverflow experience, but to be pedantic the question was "why isn't Unity JsonUtility serializing a list?" - for me reading, I am aware that it's possible to use the Newtonsoft library, or something else, but I came here wanting to know precisely the answer to that question. – PeterT Jan 26 '22 at 08:27