Is there still no way to mute 'Serialization depth limit x exceeded'?

Hi,

I had this issue before where x was 7. Now, in Unity 2020, it increased to 10.
I’d do anything possible to mute this warning. Please, if there’s someone that had success getting rid of it, please share.
I have a complex graph of C# classes, that also use generics, and I don’t even serialize them with Unity (I’m using Yaml directly). It works flawlessly, so the warning is useless for me.
I’m completely against this approach of “warning the user just to make sure ”. This kind of decisions should be backed up by an on/off switch. This warning is literally the only one showing in a pretty complex project for several years, and it’s beyond annoying.
Can anyone help?
@Tautvydas-Zilys @Aurimas-Cernius @JeffDUnity3D @xoofx

This is a bit vague what you mean by this. Does that mean you have a field inside a MonoBehaviour or ScriptableObject that is marked with NonSerialized but still causes this error? Or what does it mean when you say you don’t serialize it with Unity?

I feel as if this warning would only be showing if Unity was detecting some form of recursive serialisation, or being made to do so. If you are, then you should be using SerializeReference. If it is showing when you aren’t serialising in such a manner, that sounds like a bug to me.

Thanks for replying. It’s even simpler than that - I don’t use any part of Unity’s serialization for these classes, meaning instances of those pure C# classes are directly read from disk by YamlDotNet and passed around like in a non-Unity C# application, i.e. no fields in MonoBehaviour/ScriptableObject are declared with these types.

Thank for replying. Probably there’s some kind of recursion detected, as I’m using generics a lot, OR the class tree structure it’s just more than 10 levels (i.e. class C1 has a field of type C2, C2 has a field of type C3 … and it continues beyond C10).
But this is none of Unity serializer’s business, as long as I don’t even touch it.

This was discussed a few years ago, but I really hope that meanwhile someone found a workaround or that there’s an official way to mute the warning. Hell, maybe even a bugfix? Since this clearly is a bug.

Every result on google is about cases when people do use Unity’s serializer, and usually involve changing the class hierarchy (which in itself is not ideal for large projects).

Now I’m confused where these classes actually cross paths with Unity. Whatever you’re doing with them, they do seem to be triggering Unity’s serialisation process (perhaps the de-serialisation of these Yaml files?).

Doing a bit of reading, even distant yet recursive structures will trigger it. Such as:

  • Class A

  • Class B

  • Class C

  • Class D

  • Class E

  • Class A

Private/protected fields seem to be checked as well, even if they don’t have [SerializeField] on them. However decorating them with [NonSerialized] will get Unity to skip over them. So that’s all I can suggest at the moment.

2 Likes

Right, inside the editor also private fields are temporarily serialized when it comes to domain reloads and such things. So when you do get this error, Unity is serializing your classes at some point and for that they have to be referenced by a MonoBehaviour or ScriptableObject.

1 Like

Thanks for your replies. I’ll try putting it another way:
These classes come from an external C# solution that doesn’t reference any Unity code, and it shouldn’t.
This is actually a very stuffy C# .NET Standard 2.0 library that I’m using as a common dependency for:

  • The Client app, under Unity, imported as a package with several asmdefs for each sub-module. And again, none of these are set as serializable in a SO/MB class, but they do have the “[System.Serializable]” attribute, which is a C# thing, not a Unity thing. This is needed so that the YamlDotNet lib can recognize them.
  • The Server app, under a C# .NET 5 solution

I’ve read about the NonSerialized approach, and thanks for mentioning, as this can fix it for most folks that have a simple project structure. However, it’s just an ugly hack for an abominable bug Unity is too lazy to fix (or I hope, was, in case it’s somehow already fixed).
The reason is simple: it’s none of Unity’s business what private fields a class has, as long as they’re not marked as “[SerializeField]”, let alone trying to warn us about their entire inheritance tree (btw, what a significant performance hit I imagine this has…); it’s as if it warns “your underwear is inappropriate for this meeting”.

Anyway, still hoping there’s a proper fix. Maybe some of you know someone from Unity staff on this forum that I can tag? There might be a fix via reflection, anything…

This also tells Unity that the class can be or should be attempted to be serialised by Unity in some way shape or form. Ironically NonSerialized is is C# attribute as well. I suppose it’s one of those things that was decided upon over a decade ago and can’t exactly be changed.

So when do these errors actually occur? Domain reloads? Runtime? General Editor usage?

While these fields aren’t serialised in an SO/MB, are they actually declared or referenced in any? If they are, these would be the places to use NonSerialized I imagine, because as mentioned by Bunny, these will encounter serialisation in some temporary form (I imagine to reset values during a domain reload, for example).

I don’t think I’d call this a bug. It’s only your very peculiar, esoteric use case that’s causing this behaviour to emerge. Something you’re doing is getting Unity to run its serialisation fingers across your class hierarchy.

1 Like

Didn’t realize NonSerialized is a C# thing. Anyway, it won’t be feasible to use it all over the place on the C# lib. Redundancy & Visibility horror.
But I’ll search for private usages on the Unity-side. Will post here if I find & “fix” them. But I still wait for someone from Unity side to respond, hopefully with a proper fix. These things are not impossible to fix.

Sorry to disagree, but it is a bug, for the reasons I enumerated in the previous post. My use case is not uncommon if you make an actual, real game, with a common library that needs to be shared between the server and the client.
Just to give you a specific, failed use-case of mine (forget about code coupling that violates SOLID): referencing unity code in the server code requires you to use the same Unity DLL as in the client, which is changed, broken down into multiple DLLs and whatnot on each Unity upgrade – i.e. a lost battle from the beginning. Well, if we’d talk about a physics-based game, that’s an entire different story, as then you’d need Unity on the server-side, but here it’s a turn-based online RPG

The previous comments are correct that NonSerialized should be used on private fields to prevent Unity from serializing them during domain reloads. That extra full object serialization is intentional, it attempts to preserve objects states during domain reloads. But it is a source of confusion, especially when it pops up on fields on UI objects and other things that only indirectly derive from ScriptableObject. At this point turning off that special kind of serialization would probably also cause all sorts of problems in existing code that depends on that behaviour.

You shouldn’t need to put NonSerialized all over the place, just at whatever entry point is causing Unity to bring your data structures into the serialization, e.g. some field on a MonoBehaviour, ScriptableObject or a derived object. I hope you can track that down and get rid of that error!

3 Likes

Is there any way to track the cause of such an issue? Imagine having hundreds of monobehaviours in the project - how should one approach it to find which files are causing this?

1 Like

Well. any class that you know is serialized (which includes all MonoBehaviours or serializable classes they contain / reference) are potential sources for unwanted serialization. So if you have a private member variable in such a class that may be referencing some other things that Unity should not care about, mark it with NonSerialized. Any classes which do not belong to Unity and are not referenced by any serialized classes do not matter. So just focus on the actual Unity related classes which are serialized and think about what you want and what you don’t want to be serialized. Just making it private does not prevent the serialization in some cases.

Yeah, and now imagine a project with hundreds of classes (derived from MonoBehaviour) in it. I get what that exception means, I just want it to tell me which class I need to fix. I think that good exception should at least contains such details.

If a project was only monobehaviors you wouldn’t have this problem, as you can’t serialise a reference to another monobehaviour as values.

The issue would only be in your plain class scripts that create a circular loop of serialisation (which may be serialized across a number of Unity objects). A better starting point would be to look at your POCO scripts and see where they are used.

I am rather complaining about how non-informative this particular warning is.