What I want to achieve. I have a class that has some properties/objects in it. I want to serialize only those objects which meet the CanConvert condition with my custom serializer, others should be handled defaultly.
Problem is that with [JsonConverter(typeof(UnityObjectConverter))]
it serializes correctly but deserialization fails. Probably because I save only path to the object, not the whole object and when some internal check (which I don't get why) occurs than it fails and returns null, because the ReadJson
is never called.
When I use Settings, it causes more problems to me, that it solves because it does not serialize the rest. I don't want to have serialization for the whole class, because that way it wouldn't be very universal since several objects inherit that class. The class itself is not abstract so there might be some objects using just the class. I would be really glad if someone could help. Thanks
public class UnityObjectConverter : JsonConverter {
public override bool CanConvert(Type objectType) {
Debug.Log(objectType.BaseType == typeof(UnityEngine.Object));
return objectType.BaseType == typeof(UnityEngine.Object);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
Debug.Log("read");
return UnityEditor.AssetDatabase.LoadAssetAtPath(reader.ReadAsString(), objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
Debug.Log("write");
var item = (UnityEngine.Object)value;
writer.WriteValue(UnityEditor.AssetDatabase.GetAssetPath(item));
writer.Flush();
}
public override bool CanRead {
get {
return true;
}
}
public override bool CanWrite {
get {
return true;
}
}
}
Example of property
/// <summary>
/// GameObject if item is needed to be visualised
/// </summary>
[JsonConverter(typeof(UnityObjectConverter))]
public GameObject gameObject { get { return _gameObject; } private set { _gameObject = value; } }
protected GameObject _gameObject = null;
Example of de/serialization
public static void Add(Item i) {
items.Add(i);
if (!System.IO.File.Exists(Application.dataPath + DATA_PATH))
System.IO.File.Create(Application.dataPath + DATA_PATH).Close();
using (System.IO.StreamWriter sw = System.IO.File.CreateText(Application.dataPath + DATA_PATH)) {
sw.Write(JsonConvert.SerializeObject(items));
}
}
static void Load() {
items.Clear();
Item[] it = JsonConvert.DeserializeObject<Item[]>(System.IO.File.ReadAllText(Application.dataPath + DATA_PATH));
if (it != null)
items.AddRange(it);
}
When I did this sort of thing, I created a JsonSerializerSettings object
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
NullValueHandling = NullValueHandling.Ignore
};
settings.Converters.Add(new Converter());
Then passed that into the deserializer
var json = textReader.ReadToEnd();
return JsonConvert.DeserializeObject<T>(json, settings);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With