I have discovered a very strange serialization issue with Unity. In the screenshot, it can be seen that NewData in the script is not serialized, but ListNewDataList can be serialized correctly. This issue is really strange, and I hope someone can answer it.
This is the Unity package.
9914595–1433118–Test1.unitypackage (1.4 MB)
I’m surprised no warning is being logged in the console as this should be setting off Unity’s recursive serialisation protection.
Because Unity’s default serialisation doesn’t support null, the serialisation of TestData would go infinite, though Unity will protect against that and only let you go 10 levels deep (7 in older versions).
If you want to use this sort of recursive structure, [SerializeReference]
is required to allow null values, so the serialisation doesn’t no go infinite. Though you will need to start implementing custom inspector stuff to manage this.
Also next time, please don’t post a bunch of giant screenshots. Post code using code tags, and some cropped screenshots to explain the issue.
Thank you very much for your reply. I did as you said, and the console displayed 3 messages:
[Worker1] Serialization depth limit 10 exceeded at ‘TestData.NewData’. There may be an object composition cycle in one or more of your serialized classes.
Serialization hierarchy:
11: TestData.NewData
10: TestData.NewDataList
9: TestData.NewDataList
8: TestData.NewDataList
7: TestData.NewDataList
6: TestData.NewDataList
5: TestData.NewDataList
4: TestData.NewDataList
3: TestData.NewDataList
2: TestData.NewDataList
1: TestData.NewDataList
0: Data.testdata
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
Serialization depth limit 10 exceeded at ‘TestData.NewData’. There may be an object composition cycle in one or more of your serialized classes.
Serialization hierarchy:
11: TestData.NewData
10: TestData.NewDataList
9: TestData.NewDataList
8: TestData.NewDataList
7: TestData.NewDataList
6: TestData.NewDataList
5: TestData.NewDataList
4: TestData.NewDataList
3: TestData.NewDataList
2: TestData.NewDataList
1: TestData.NewDataList
0: Data.testdata
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
Serialization depth limit 10 exceeded at ‘TestData.NewData’. There may be an object composition cycle in one or more of your serialized classes.
Serialization hierarchy:
11: TestData.NewData
10: TestData.NewDataList
9: TestData.NewDataList
8: TestData.NewDataList
7: TestData.NewDataList
6: TestData.NewDataList
5: TestData.NewDataList
4: TestData.NewDataList
3: TestData.NewDataList
2: TestData.NewDataList
1: TestData.NewDataList
0: Test.testdata
I don’t know how to solve this problem, please help me, I really need help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class TestData
{
[SerializeReference] public TestData NewData;
public List<TestData> NewDataList = new List<TestData>();
// Start is called before the first frame update
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New GameData",menuName = "Purple Star Frame/New GameData")]
public class Data : ScriptableObject
{
public TestData testdata;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class Test : MonoBehaviour
{
public Transform Cylinder;
public Transform Capsule;
public List<Data> Objects;
public TestData testdata;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void OnClick()
{
}
}
Thank you for your reply. I feel like this is a bug with Unity, and I can only make changes to the code now. Perhaps I should report this issue to the developers at Unity.
There’s no problem with Unity in this particular instance. This is how Unity has worked for years. Default serialisation doesn’t support null. Meaning recursively serialised types go infinite, something Unity guards against and warns about.
[SerializeReference]
supports null, but there is next-to-no built in inspector and selection support for it (so I guess there is a problem, but not directly related to this). Hence why I mentioned the need for custom inspector work.
I wrote a simple example of how to get subtype selection here: abstract SkillList that can be edited in Inspector
Though with recursive structures you’ll likely need to implement something more custom.
Let’s go a step back here and look at it: What’s the purpose of the code? Why does TestData have a member list containing TestData?
Just have a class TestDataStorage to hold this list and the whole issue disappears.
It’s really rare that recursive reference storage is the best solution for a problem.
Your idea is very interesting. Can you send the code? Although I have now resolved this issue by modifying the code.
Cannot write targetted code without knowing what it’s supposed to do exactly…
Glad you solved the problem.
thank you.