使用Newtonsoft.Json序列化unity中的数据时报错rigidbody property has been deprecated解决方案

详细报错如下:NotSupportedException: rigidbody property has been deprecated
(wrapper dynamic-method) System.Object.lambda_method(System.Runtime.CompilerServices.Closure,object)
Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue (System.Object target) (at /root/repo/Src/Newtonsoft.Json/Serialization/

不同的开发者报错可能会有细微不同,例如上文中的rigidbody可能换成了camera,rigidbody2D,camera等等,其实这些报错的根本原因是一样的,因为它们的共同点都是Unity的内置组件,通常是"MonoBehaviour"的子类,由于这些组件往往含有Unity引用或者其他非序列化字段,所以直接序列化这些组件会导致问题。解决方案有两个,各位根据自己实际情况任选其一即可。

解决方案一:

自定义一个"ContractResolver"来排除无法正常序列化的属性,首先创建一个类,它会检查每个属性,如果属性名是"rigidbody",则不会将其包含在序列化的JSON中,然后在我们自己的save代码所在的序列化类当中使用这个自定义的"ContractResolver"。话不多说,贴代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Reflection;

public class CustomContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        //排除名为"rigidbody"的属性
        if(property.PropertyName == "rigidbody" )
        {
            property.ShouldSerialize = instance => false;
        }

        return property;
    }
}

然后假设你有这样一个Save()方法,在方法内添加如下代码即可:

public void Save1()
    {
        int a = 1;//举例用的数据,各位开发者根据实际需求换成自己的数据即可

        JsonSerializerSettings settings = new JsonSerializerSettings
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
            ContractResolver = new CustomContractResolver()//使用自定义的ContractResolver
        };

        var jsonData = JsonConvert.SerializeObject(a, settings);
    }

如果运行代码后,报错中的rigidbody换成了别的属性,那么只需要在第一段代码中的排除属性部分添加||符号来增加其他的报错属性即可。

解决方案二:

还是只需要改变第一段代码中的排除部分,其他代码与方案一相同。代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Reflection;

public class CustomContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        //排除所有在UnityEngine命名空间下的属性
        if(member.DeclaringType.Namespace == "UnityEngine")
        {
            property.ShouldSerialize = instance => false;
        }

        return property;
    }
}

注意:方案二是一刀切的方法,可以保证不报错,但是有些需要序列化的数据可能会无法成功序列化,导致项目保存出现问题!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值