【问题标题】:Unity C# JsonUtility is not serializing a listUnity C# JsonUtility 未序列化列表
【发布时间】:2017-01-22 03:42:54
【问题描述】:

我有一些需要序列化/反序列化的数据,但 JsonUtility 并没有做它应该做的事情。这是我正在使用的对象:

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

public class SpriteDataCollection
{
    public SpriteData[] sprites;
}

如果我创建一个 SpriteDataCollection,并尝试使用 JsonUtility 对其进行序列化,我只会得到一个空对象 {}。以下是它的构建方式:

            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));

调试日志只打印“{}”。为什么它不序列化任何东西?我已经对其进行了测试,序列化单个 SpriteData 完全符合它的预期,但它在 SpriteDataCollection 中不起作用。

【问题讨论】:

    标签: c# json unity3d serialization


    【解决方案1】:

    有 4 个已知可能的原因导致您在 Unity 中得到空 Json。

    1。不包括[Serializable]。如果你不包含这个,你会得到空的 json。

    2.使用属性 (get/set) 作为变量。 JsonUtility 不支持这个。

    3.尝试序列化List以外的集合。

    4.您的 json 是多数组,JsonUtility 不支持,需要wrapper 才能工作。

    问题看起来像 #1。您在课堂上缺少[Serializable]。您必须添加 using System; 才能使用它。

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

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

    5。就像上面在SpriteData 类中给出的示例一样,变量必须是公共变量。如果是私有变量,则在其顶部添加[SerializeField]

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

    如果仍然无法正常工作,那么您的 json 可能无效。从"Serialize and Deserialize Json and Json Array in Unity" 帖子的答案中阅读“4.TROUBLESHOOTING JsonUtility”。这应该让您了解如何解决这个问题。

    【讨论】:

    • 我认为这是某种魔术标签或我必须做的事情,谢谢。它现在按预期工作。
    • 我刚遇到这个问题,对我来说问题是 5。我的字段没有标记为公开。我知道这在规则中,只是我忘记了。
    • @KylePostlewait 如果它是私有的,则不会被序列化,这是常识。不过,您可以将 [SerializeField] 放在私有字段的顶部以使其序列化。
    • 嗯 1 2 3 和 4 也是相当常识,我只是想我会添加它以完成,因为它是我 bumble 的第一个谷歌结果。
    • @KylePostlewait #4 中的示例对所有内容都使用了public,但我修改了答案以包含它。
    【解决方案2】:

    另一个原因程序员没有提到但很固执:

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

    如果使用readonly,列表将不会序列化。例如

    MyCollection collection = new MyCollection();
    collection.myObjects.Add(new MyObject {someField = "Test"});
    string json = JsonUtility.ToJson(collection);
    // {}
    

    【讨论】:

      【解决方案3】:

      我通过使用 Newtonsoft 而不是 JsonUtility 作为转换器解决了这个问题。

      这是一个例子

      //这里我们将序列化或反序列化数据

      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);
      }
      

      //这是模型

      public class Model
      {
          public DateTime saveTime;
      
          public int playerHealth;
      
          public int strength;
      
      }
      

      这里是结果

      【讨论】:

        【解决方案4】:

        Unity3D 有一个老式的 Json 库。您可以使用 Newtonsoft.Json,这是 .NET 生态系统中的标准 JSON 库。但是,它不支持 Unity3D,您需要获取 Unity3D 的专用包。您可以从它的GithubUnity 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);
        

        请注意,SerializableAttribute 应该应用于 The_Object 类和其中任何使用的对象类型。此外,您必须将要通过 json 解析的变量指示为公共变量。 例如:

        [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;
        
            //....
        }
        

        【讨论】:

        • 这个答案基于我的工作代码。我想知道你为什么投反对票?
        • 我不知道你为什么被否决,很抱歉你有一个不友好的 StackOverflow 体验,但为了迂腐,问题是“为什么 Unity JsonUtility 不序列化列表?” - 对我来说,我知道可以使用 Newtonsoft 库或其他东西,但我来到这里想确切地知道这个问题的答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-24
        • 2017-12-01
        相关资源
        最近更新 更多