Можно ли как-то сериализовать ClassA, включая вложенные классы, в один файл JSON?
Да, вы могли бы, но это потребовало бы некоторой работы:
Вы можете иметь [Serializable]
классы представления для ClassB
и ClassC
и использовать ISerializationCallbackReceiver
интерфейс для заполнения и использовать их в ClassA
Нечто подобное, например,
public class ClassB : MonoBehaviour
{
[SerializeField] private float example1;
[SerializeField] private string example2;
// etc.
public void SetUp(SerializableClassB values)
{
// set all values
this.example1 = values.example1;
this.example2 = values.example2;
// etc.
}
public SerializableClassB GetSerializable()
{
var output = new SerializableClassB();
output.example1 = this.example1;
output.example2 = this.example2;
// etc.
return output;
}
}
[Serializable]
public class SerializableClassB
{
public float example1;
public string example2;
// etc
}
И то же самое для ClassC
public class ClassC : MonoBehaviour
{
[SerializeField] private float example3;
[SerializeField] private string example4;
// etc.
public void SetUp(SerializableClassC values)
{
// set all values
example3 = values.example3;
example4 = values.example4;
// etc.
}
public SerializableClassC GetSerializable()
{
var output = new SerializableClassC();
output.example3 = example3;
output.example4 = example4;
// etc.
return output;
}
}
[Serializable]
public class SerializableClassC
{
public float example3;
public string example4;
// etc
}
Тогда в ClassA
вы можете сделать
public class ClassA : MonoBehaviour, ISerializationCallbackReceiver
{
public ClassB _classB;
public ClassC _classC;
[SerializeField] private SerializableClassB _serializableClassB;
[SerializeField] private SerializableClassC _serializeableClassC;
public void OnBeforeSerialize()
{
// before writing to a Json get the information from the MonoBehaviours into the normal classes
if(_classB) _serializableClassB = _classB.GetSerializable();
if(_classC) _serializeableClassC = _classC.GetSerializable();
}
public void OnAfterDeserialize()
{
// after deserializing write the infromation from the normal classes into the MonoBehaviours
if(_classB) _classB.SetUp(_serializableClassB);
if(_classC) _classC.SetUp(_serializeableClassC);
}
}
Вторым огромным преимуществом (побочным эффектом) является то, что теперь вы дополнительно можете также контролировать значения _classB
и _classC
непосредственно в экземпляре ClassA
. Таким образом, вы можете изменять значения MonoBehaviour в классе централизованного менеджера.
![enter image description here](https://i.stack.imgur.com/pgxxE.gif)
После сериализации в JSON с использованием
private void Start()
{
File.WriteAllText(Path.Combine(Application.streamingAssetsPath, "Test.txt"), JsonUtility.ToJson(this));
AssetDatabase.Refresh();
}
теперь вы получите
{
"_classB":{"instanceID":-6766},"_classC":{"instanceID":-6826},
"_serializableClassB": {
"example1":23.0,
"example2":"54ththfghg"
},
"_serializeableClassC": {
"example3":67.0,
"example4":"567gffhgfhgf"
}
}
Чем для примера я изменил его на
{
"_classB":{"instanceID":-6766},"_classC":{"instanceID":-6826},
"_serializableClassB": {
"example1":47,
"example2":"Hello"
},
"_serializeableClassC": {
"example3":32.123,
"example4":"World!"
}
}
и десериализовано при запуске из json с использованием
private void Start()
{
JsonUtility.FromJsonOverwrite(File.ReadAllText(Path.Combine(Application.streamingAssetsPath, "Test.txt")), this);
}
![enter image description here](https://i.stack.imgur.com/I0u1P.gif)