Unity C# JsonUtility 未序列化列表
Posted
技术标签:
【中文标题】Unity C# JsonUtility 未序列化列表【英文标题】:Unity C# JsonUtility is not serializing a list 【发布时间】: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 中不起作用。
【问题讨论】:
【参考方案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 的专用包。您可以从它的Github 或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);
请注意,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;
//....
【讨论】:
这个答案基于我的工作代码。我想知道你为什么投反对票? 我不知道你为什么被否决,很抱歉你有一个不友好的 *** 体验,但为了迂腐,问题是“为什么 Unity JsonUtility 不序列化列表?” - 对我来说,我知道可以使用 Newtonsoft 库或其他东西,但我来到这里想确切地知道这个问题的答案。以上是关于Unity C# JsonUtility 未序列化列表的主要内容,如果未能解决你的问题,请参考以下文章
Unity中使用JsonUtility.FromJson反序列化JSON
无法在 Unity 5.4 中使用 JsonUtility 反序列化 JSON。子集合始终为空
使用 Unity JsonUtility 反序列化 JSON 数组无法获取序列化值