I've been successfully writing and parsing back (recursively) my data using a custom JsonConverter, using this:
public override void WriteJson(JsonWriter writer, ManagedSubData value, JsonSerializer serializer)
{
skipOverMe = true;
value.GrabAssetPath();
writer.WriteValue(JsonConvert.SerializeObject(value));
}
The problem is, this gives me an unreadable Json full of backslashes everywhere. Now, I can use this instead of WriteValue, and it outputs a nice readable Json:
writer.WriteRawValue(JsonConvert.SerializeObject(value));
But when I try to read it back, it fails. reader.Value is now null, it's like it failed before even calling ReadJson
public override ManagedSubData ReadJson(JsonReader reader, Type objectType, ManagedSubData existingValue,
bool hasExistingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
//fails here since reader.Value is null
JObject obj = JObject.Parse(reader.Value.ToString());
ManagedSubData asset = ManagedDataHandler.GetSubDataFromGUID(obj["GUID"].ToString());
if (asset == null)
{
asset = ScriptableObject.CreateInstance(objectType) as ManagedSubData;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
AssetDatabase.CreateAsset(asset, obj["assetPath"].ToString());
AssetDatabase.SaveAssets();
}
#endif
}
if (!asset.KeepPlayModeChanges)
{
JsonConvert.PopulateObject(reader.Value.ToString(), asset);
asset.SetDirty();
}
return asset;
}
There are actual field values if I try to do reader.Read, it's just that the Value of the object itself is considered null.
Maybe I shouln't be trying to write Raw value? I am noticing that for every level of nesting, WriteValue adds additional slashes, but maybe it needs those to parse it back?
Does anyone have any ideas? We kinda need the Json to be readable and not full of garbage.
I think the main problem is that you don't really understand the difference between WriteRawValue and WriteValue, they are not the same thing and there is a reason why using WriteValue give you a string with escape instead of a clean json.
Take a look here: Is there an equivalent for JRaw in System.Text.Json
You want to use WriteRawValue only when your string is already a json object, but I think in your specific scenario it is better to just create an object of your json data and actually serialize it.
EDIT. Example based on your possible json
YourJsonObject.cs
ComplexObject.cs
PS. Since you need to serialize Unity complex object like ScriptableObject you should use Unity3d default serializer
https://docs.unity3d.com/2021.2/Documentation/Manual/JSONSerialization.html
Warning: The JSON Serializer API supports MonoBehaviour and ScriptableObject subclasses as well as plain structs and classes. However, when deserializing JSON into subclasses of MonoBehaviour or ScriptableObject, you must use the FromJsonOverwrite method. If you try to use FromJson, Unity throws an exception because this behavior is not supported.