1

我正在尝试为资产对象创建一个方便的序列化引用。它正确序列化,但反序列化失败并出现异常

“在 'TestData' 上将值设置为 'textAssetRef' 时出错。”

我为 Unity 准备了一个小测试组件来说明这一点:

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEditor;
using UnityEngine;

public class Test : MonoBehaviour
{
    public TestData testData;

    public void Awake()
    {
        try
        {
            var sData = JsonConvert.SerializeObject(testData, Formatting.Indented);
            UnityEngine.Debug.Log(sData);
            testData = JsonConvert.DeserializeObject<TestData>(sData);
            UnityEngine.Debug.Log("Done.");
        }
        catch (Exception x)
        {
            UnityEngine.Debug.LogError(x.Message);
        }
    }
}


[Serializable]
public class TestData
{
    public TextAssetRef textAssetRef;
}


[Serializable]
[JsonConverter(typeof(Serialization))]
public class TextAssetRef : ObjectRef<TextAsset>
{
    public TextAssetRef() { }
    public TextAssetRef(TextAssetRef other) : base(other) { }
    public TextAssetRef(TextAsset ta) : base(ta) { }
}


[Serializable]
public class ObjectRef<T> where T : UnityEngine.Object
{
    public T obj;

    public ObjectRef() { }
    public ObjectRef(ObjectRef<T> other) { obj = other.obj; }
    public ObjectRef(T obj) { this.obj = obj; }


    public class Serialization : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var objRef = (ObjectRef<T>)value;
            var jObject = new JObject { { "path", AssetDatabase.GetAssetPath(objRef.obj) } };
            serializer.Serialize(writer, jObject);
        }

        public override bool CanConvert(Type objectType) { return objectType == typeof(ObjectRef<T>); }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jObject = JObject.Load(reader);
            var assetPath = jObject.GetValue("path").Value<string>();
            return new ObjectRef<T> { obj = AssetDatabase.LoadAssetAtPath<T>(assetPath) };
        }
    }
}

要重现错误,只需在 Unity 中使用 JSON.Net 资产包创建一个新项目,在场景中创建空对象,将此测试组件放在其上,然后按播放。

我该怎么做才能正确反序列化它?

4

0 回答 0