У меня есть ситуация, когда мне нужно сериализовать любой GameObject
как что-то еще внутри (GameObjectMetadata
), которое содержит данные, полезные для его повторной десериализации позже.
public struct GameObjectMetadata
{
public string AssetFullPath;
public string AssetBundle;
public string GUID;
public string UnityType;
}
public struct TestPrefabLink
{
public GameObject Prefab;
}
Я действительно изо всех сил пытаюсь реализовать конвертеры JSON.NET, необходимые для этого. Я занимался этим некоторое время и придумал приведенный ниже код. В основном это работает, но я получаю следующую ошибку:
JsonSerializationException: неожиданный токен при десериализации объекта: EndObject. Путь 'Components.$values[0]', строка 14, позиция 7. Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (читатель Newtonsoft.Json.JsonReader, тип объекта System.Type, контракт Newtonsoft.Json.Serialization.JsonContract, контракт Newtonsoft. Член Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existsValue) (в C:/Development/Releases/Json/Working/Newtonsoft.Json/Working-Signed /Src/Newtonsoft.Json/Сериализация/JsonSerializerInternalReader.cs:336)
Сериализатор:
data = JsonConvert.SerializeObject(blueprint, Formatting.Indented,
new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Include,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Converters = new List<JsonConverter>() { new GameObjectMetadataJsonConverter(), new UnityObjectJsonConverter() }
});
Используемые преобразователи:
public class GameObjectMetadataJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var jobj = JObject.FromObject(value);
jobj.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var metadata = serializer.Deserialize<GameObjectMetadata>(reader);
// Snipped - Code here successfully converts to GameObject
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof (GameObjectMetadata);
}
}
public class UnityObjectJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(UnityEngine.Object).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return existingValue; // This should not be called. But it is??
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var metadata = new GameObjectMetadata();
metadata.UnityType = value.GetType().ToString();
var path = UnityEditor.AssetDatabase.GetAssetPath((UnityEngine.Object)value);
var bundleName = UnityEditor.AssetImporter.GetAtPath(path).assetBundleName;
var guid = UnityEditor.AssetDatabase.AssetPathToGUID(path);
metadata.AssetBundle = bundleName;
metadata.AssetFullPath = path;
metadata.GUID = guid;
//var jobj = JObject.FromObject(metadata);
//jobj.WriteTo(writer);
serializer.Serialize(writer, metadata);
}
}
Кажется, все, что я здесь делаю, вызывает плохую запись JSON. Но я не могу понять, как еще написать другую структуру/класс от ожидаемой.