Unity:版本5.0以来的序列化问题(父/子关系)

时间:2015-03-11 23:32:12

标签: c# serialization unity3d

当我使用较旧版本的Unity时没有问题,但是自从uppgrade我继续在类包含其类型的子类的所有类上收到错误:序列化深度限制超过'形成'。在一个或多个序列化类中可能存在对象组合循环。

我有一个这样的课程:

[Serializable]
public class Formation {
    public List<Formation> Formations;
}

它写了一些循环,但为什么在没有无限循环时会出现任何问题,因为每个子实例都必须初始化,所以如果用户想要进行无限循环,他会这样做,但只能通过明确初始化子项...

这是一些错误吗?我在论坛上已经读过一些建议删除孩子的帖子,但我不知道为什么会出现这种情况。

顺便说一下我上次写的这篇课程,我甚至连序列化,甚至没有制作列表实例

3 个答案:

答案 0 :(得分:1)

我有类似的循环序列化问题。我通过显式地使父实例不可序列化来解决它。

e.g。

[Serializable]
class A
{
    [SerializeField]
    B _bInstance;
    ...
}
...
[Serializable]
class B
{
    A _aInstance;
    ...
}

变为

[Serializable]
class A
{
    [SerializeField]
    B _bInstance;
    ...
}
...
[Serializable]
class B
{
    [NonSerialized]
    A _aInstance;
    ...
}

希望这会有所帮助。

答案 1 :(得分:0)

嗯,说实话很明显......这是因为执行序列化时会发生什么。跟我说吧:你有一个班级Formation,其中包含Formation个集合。那些是Formation类型,所以每个都有一个集合。等等......周期实际上是无限的。

Formation
     List
           Formation
                 List
                      Formation
                                List
                                      ....

最简单的修复方法是将集合移动到更有意义的类(在Formation之外)。我不认为Formation里面应该有更多Formation s的列表......

答案 2 :(得分:0)

基本上,这个问题可以通过将所有可以拥有相同类型子节点的对象存储在Container中来解决,该Container将处理序列化中的子节点 - 父节点关系。 这是一个例子:

using System;
using System.Runtime.Serialization;
using System.Collections.Generic;

[Serializable]
public class MyObject
{
    [NonSerializeble]
    public MyObject child;
}

//this is the class that you are going to serialize
[Serializable]
public class ObjectsContrainer
{
    private List<MyObject> allObjects;
    private List<serializationInfo> serializationInfos;

    //save info about the children in a way that we dont get any cycles
    [OnSerializing]
    private void OnSerializingStarted(StreamingContext context)
    {
        serializationInfos = new List<serializationInfo>();
        foreach (var obj in allObjects)
        {
            serializationInfo info = new serializationInfo {
                parentIndex = allObjects.FindIndex(x => x == obj),
                childIndex =  allObjects.FindIndex(x => x == obj.child)
            serializationInfos.Add(info);
        }
    }

    //restore info about the children
    [OnDeserialized]
    private void OnDeserialized(object o)
    {
        //restore connections
        foreach (var info in serializationInfos)
        {
            var parent = allObjects[info.parentIndex];
            parent.child = allObjects[info.childIndex];
        }
    }

    [Serializable]
    private struct serializationInfo
    {
        public int childIndex;
        public int parentIndex;
    }
}