Я пытаюсь сериализовать файл сохранения, но Json.net не может сериализовать классы, производные от Monobehaviour. Ошибка, которую он дает мне, выглядит следующим образом
NotSupportedException: rigidbody property has been deprecated
В этом проекте нигде не используются жесткие тела, поэтому эта ошибка меня очень смущает. Возможно, стоит отметить, что я использую старую версию Json.net(3.5.8), так как это последняя версия, которая поддерживает структуру проектов(3.5)
Сам файл сохранения не является производным от Monobehaviour, но внутри него есть соответствующие свойства. Это приводит к появлению ошибки.
Это код, который я использую для проверки сериализации, как вы можете видеть, он должен сериализовать сохранение, распечатать результат, десериализовать его, а затем снова распечатать.
var test1 = JsonConvert.SerializeObject(SaveManager.currentSave, Formatting.Indented, new JsonSerializerSettings()
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
Debug.Log(test1);
var test2 = JsonConvert.DeserializeObject<Save>(test1);
Debug.Log(test2);
Сохранить курс
using System.Collections.Generic;
using UnityEngine;
namespace Com.BlewScreen.Woongame
{
[System.Serializable]
public class Save
{
private bool initialSave = true;
private string saveName;
//Player var
private House house;
private string districtHouseName;
private House wantsToMove;
private string districtWantsToMoveToName;
[System.NonSerialized]
public District houseDistrict;
[System.NonSerialized]
public District wantsToMoveToDistrict;
private int income;
private int health;
private int balance;
private int livingpleasure;
private int regtime;
private bool disabled;
private bool hasPartner;
private int kids;
private int livingSituationCount;
//Housing market var
private DistrictStats a; //Tom: Change this to "DistrictStatsA" etc. instead of just a, b, c, d, e
private DistrictStats b;
private DistrictStats c;
private DistrictStats d;
private DistrictStats e;
private string characterIndexes;
public string CharacterIndexes { get; set; }
public string characterSkinTone;
public string CharacterSkinTone { get; set; }
public House House
{
get{ return house; }
set{ house = value; }
}
public House WantsToMove
{
get{ return wantsToMove; }
set{ wantsToMove = value; }
}
public int Income
{
get { return income; }
set{ income = value; }
}
public int Health
{
get{ return health; }
set{ health = value; }
}
public int Balance
{
get{ return balance; }
set{ balance = value;}
}
public int Livingpleasure
{
get{ return livingpleasure;}
set{ livingpleasure = value;}
}
public int Regtime
{
get{ return regtime;}
set{ regtime = value;}
}
public bool Disabled
{
get{ return disabled;}
set{ disabled = value;}
}
public bool HasPartner
{
get{ return hasPartner;}
set{ hasPartner = value;}
}
public int Kids
{
get{ return kids;}
set{ kids = value;}
}
public DistrictStats A
{
get{ return a;}
set{ a = value;}
}
public DistrictStats B
{
get{ return b; }
set{ b = value;}
}
public DistrictStats C
{
get{ return c;}
set { c = value;}
}
public DistrictStats D
{
get{ return d;}
set{ d = value;}
}
public DistrictStats E
{
get{ return e;}
set{ e = value; }
}
public string DistrictHouseName
{
get{ return districtHouseName;}
set{ districtHouseName = value; }
}
public string DistrictWantsToMoveToName
{
get{ return districtWantsToMoveToName;}
set{ districtWantsToMoveToName = value; }
}
public bool InitialSave
{
get{ return initialSave; }
set{ initialSave = value;}
}
public int LivingSituationCount
{
get{ return livingSituationCount;}
set{ livingSituationCount = value; }
}
public string SaveName
{
get{ return saveName; }
set{ saveName = value; }
}
public Save()
{
InitialSave = true;
}
public Save(string saveName, House house, House wantsToMove,
int income, int health, int balance, int livingpleasure,
int regtime, bool disabled, bool hasPartner, int kids,
int livingSituationCount, DistrictStats a, DistrictStats b,
DistrictStats c, DistrictStats d, DistrictStats e, string characterIndexes, string characterSkinTone)
{
initialSave = false;
DistrictHouseName = house.District.DistrictName;
if (wantsToMove != null)
{
DistrictWantsToMoveToName = wantsToMove.District.DistrictName;
}
this.saveName = saveName;
this.House = house;
this.WantsToMove = wantsToMove;
this.Income = income;
this.Health = health;
this.Balance = balance;
this.Livingpleasure = livingpleasure;
this.Regtime = regtime;
this.Disabled = disabled;
this.HasPartner = hasPartner;
this.Kids = kids;
this.LivingSituationCount = livingSituationCount;
A = a;
B = b;
C = c;
D = d;
E = e;
this.CharacterIndexes = characterIndexes;
this.CharacterSkinTone = characterSkinTone;
}
}
}
Полный стек ошибок
NotSupportedException: rigidbody property has been deprecated UnityEngine.GameObject.get_rigidbody () (at C:/buildslave/unity/build/Runtime/Export/GameObject.deprecated.cs:23) (wrapper dynamic-method) UnityEngine.GameObject.Getrigidbody (object) Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue (object) Rethrow as JsonSerializationException: Error getting value from 'rigidbody' on 'UnityEngine.GameObject'. Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue (System.Object target) Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContract collectionValueContract)
Объекты, включаемые в сохранение, получены из GameObject? Это не имеет ничего общего с Json.Net, а скорее с устаревшими функциями единства.
@KristófTóth, например, в доме собственности есть свойство, называемое районом, которое происходит от Monobehaviour и содержит в себе элементы GameObject.
Я наткнулся на сообщение о сериализации Unity 5 GameObject, но дело в том, что в этом проекте не используются жесткие тела, поэтому также нет вызовов жестких тел.
Спасибо, что это проблема, поскольку вы пытаетесь сериализовать весь объект-контейнер, в конечном итоге он достигнет устаревших свойств и выдаст исключение из-за устаревших функций. Проверьте ветку, упомянутую выше, она предоставит вам решение
В сообщении, упомянутом выше, говорится только о том, что нельзя называть твердым телом по-старому, однако я не использую никаких жестких тел @KristófTóth.





Вы не можете сериализовать MonoBehaviour или любой компонент Unity.
Эта ошибка, скорее всего, вызвана тем, что Json.net пытается получить значение свойства .rigidbody, и, поскольку оно устарело, это вызывается.
Поэтому, если бы этой ошибки удалось избежать, процесс все равно завершился бы неудачей. Удалите все моноповедения из своего сохранения или создайте новый класс, содержащий данные, которые вы хотите сохранить.
Правильный. Просто сериализуйте то, что вам нужно, а не всю стрельбу.
так как же можно сериализовать такие данные?
Есть несколько вариантов:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)] в класс компонента и добавьте атрибут [JsonProperty] в свойство/поле.Эти параметры не подходят для моего варианта использования, поскольку у меня есть несколько компонентов и свойств, которые нужно сериализовать. Я также хочу включить свойство name из UnityEngine.Object, но мы не можем добавить атрибут в класс.
Что я сделал, так это переопределил метод CreateProperties в моем КонтрактРезолвер.
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var properties = base.CreateProperties(type, memberSerialization);
// Only filter class that is derived from MonoBehaviour
if (type.IsSubclassOf(typeof(MonoBehaviour)))
{
// Keep name property OR properties derived from MonoBehaviour
properties = properties.Where(x => x.PropertyName.Equals("name") || x.DeclaringType.IsSubclassOf(typeof(MonoBehaviour))).ToList();
}
return properties;
}
Возможный дубликат Сериализация GameObject в Unity 5