假设我有一个名为 ObjectA
的对象,它包含两个对象:ObjectsB
和 ObjectC
。
[System.Serializable]
public ClassA
{
public ClassB classB;
public ClassC classC;
public ClassA()
{
classB = new ClassB();
classC = new ClassC();
}
}
[System.Serializable]
public ClassB
{
//Some fields.
}
[System.Serializable]
public ClassC
{
//Some fields.
}
如果我将 ObjectA
序列化为 JSON,ObjectB
和 ObjectC
不会被序列化。这是我将 ObjectA
序列化为 JSON 后得到的:
{"_instanceB":{"instanceID":10480},"_instanceC":{"instanceID":10230}}
我需要将所有这些对象序列化为一个文件并将其保存在本地硬盘上,以便以后能够恢复它们的状态。我该怎么做?
我是否应该从 ClassA
中检索 ClassB
和 ClassC
然后序列化并分别保存它们?像这样:
public void Save()
{
//Get instances of ClassB and ClassC.
ClassB classB = classA.GetClassB;
ClassC classC = classA.GetClassC;
//Generate different JSON for each class.
string classA_JSON = JsonUtility.ToJson(classA);
string classB_JSON = JsonUtility.ToJson(classB);
string classC_JSON = JsonUtility.ToJson(classC);
//Paths for saving locally.
string pathForClassA = Path.Combine("C:\\", "classA.json");
string pathForClassB = Path.Combine("C:\\", "classB.json");
string pathForClassC = Path.Combine("C:\\", "classC.json");
File.WriteAllText(pathForClassA, classA_JSON);
File.WriteAllText(pathForClassB, classB_JSON);
File.WriteAllText(pathForClassC, classC_JSON);
}
看起来很难看,它会为每个嵌套类生成一个新的 JSON 文件。我能否以某种方式将 ClassA
及其嵌套类序列化为一个 JSON 文件?
P.S. 这是一个 Unity 项目,ClassA
、ClassB
和 ClassC
派生自 MonoBehaviour
。由于 BinaryFormatter
不支持 MonoBehaviour
我无法使用它。唯一留给我的就是将它序列化为 JSON。
最佳答案
Can I somehow serialize ClassA including its nested classes into one JSON file?
是的,你可以,但它需要一些工作:
您可以为 ClassB
和 ClassC
使用 [Serializable]
表示类,并使用 ISerializationCallbackReceiver
interface用于在 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);
}
}
第二个巨大的优势(副作用)是现在您还可以直接在 ClassA
上控制 _classB
和 _classC
的值> 实例。这样您就可以在集中式管理器类中修改 MonoBehaviour 值。
序列化为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);
}
关于c# - 有没有办法将引用的 MonoBehaviours 序列化为 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56569824/