Search Unity

Bug How to stop unity from serializing c# Properties in the editor?

Discussion in 'Editor & General Support' started by Flavelius, Feb 12, 2021.

  1. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    I had this problem before where unity printed serialization depth warnings where none should have been printed.
    This turned out to be due to unity ignoring its own serialization rules in the editor and serializing 'c# Properties' (not c# fields that unity tends to call properties) anyway (something to do with supporting hotreload i think i've been told).
    Now i'm at this point again where i get this warning in a fairly complex project, but the editor also intelligently not includes info about where it tried to serialize things it wasn't supposed to.
    How can i disable this bugfeature altogether?
     
  2. ErnestSurys

    ErnestSurys

    Joined:
    Jan 18, 2018
    Posts:
    94
    I don't think Unity is secretly serializing properties, but if you want you can prevent fields from being serialized with NonSerializedAttribute.
     
    Tom980 likes this.
  3. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    Unfortunately it actually does (i had that confirmed by the devs), technically, it's serializing the backing field of the property. But for big projects it's not feasible to be forced to decorate every auto property with [field:NonSerialized] just to make unity behave correctly (abiding by its own rules).
    A way to disable hot reload (and thus this hotreload-hack) or something similar would be helpful, similar to fast-enter-playmode (where they're open about the consequences).

    Edit: i even found the original conversation (screenshot):
    upload_2021-2-13_10-17-10.png

    I still find it hard to believe the devs actually think that this is 'expected behaviour' and not a bug as this can lead to unwanted sideeffects with custom ISerializationCallbackListener logic and situations where their serialization system deems it ok to fail.
     
    Last edited: Feb 13, 2021
  4. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Ah, is this about the age-old "The same field has been serialized multiple times” error?
    Yeah, that's a bizarre one that, like the OP states, is applying to non-serialized properties (and fields).

    After experimenting with it for a while, I found that it seems to occur when a class has a field/property named the same name as another field/property from a
    MonoBehavior
    it's inheriting from, even if they're set to
    private
    :
    Code (CSharp):
    1. public class Parent : MonoBehavior {
    2.    private int SomeInt { get; set; }
    3. }
    4.  
    5. public class Child : Parent {
    6.    private int SomeInt { get; set; }
    7. }
    The only way to get around it is to ensure that the field/property names are unique for every inherited
    MonoBehavior
    type:
    Code (CSharp):
    1. public class Parent : MonoBehavior {
    2.    private int Parent_SomeInt { get; set; }
    3. }
    4.  
    5. public class Child : Parent {
    6.    private int Child_SomeInt { get; set; }
    7. }
    I do agree that this shouldn't be considered a "feature", it's outright nonsense.
     
  5. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    @Vryken that's not a 'Bug' or a 'Feature'. You're simply breaking inheritance (Pure C#, no Unity involved).
    Even though Child cannot 'access' the private SomeInt of Parent, it still inherits it.
    If a method in Parent utilizes the SomeInt-Property, it will do so even if the Object is of type Child (as Child will inherit both the Method and the Property). Thus it needs that Property to be 'unique'.

    Edit: This is also why the 'new' modifier exists:
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/new-modifier
     
  6. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Fair enough, that makes sense.
    Though if this is "breaking inheritance", why even allow it to compile then? Shouldn't this just throw a compile-time error to prevent it from being done in the first place?

    The new keyword doesn't prevent Unity from displaying the error. Still happens even in a setup like this:
    Code (CSharp):
    1. public class Parent : MonoBehavior {
    2.    public int SomeInt { get; set; }
    3. }
    4.  
    5. public class Child : Parent {
    6.    public new int SomeInt { get; set; }
    7. }
     
  7. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    After thinking about it a bit more, I'm guessing the compiler would/should be smart enough to just use 2 separate 'names' internally for the Properties, which would prevent them from conflicting. In the end; they're all just pointers.

    However:
    Unity does a lot of stuff through Reflection (including Serialization).
    My guess would be that THAT is where the 'duplicate naming' issue might become a problem?
     
  8. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    The issue with this is that unity flattens the hierarchy to an extent when de/serializing, so the serialized data would contain duplicate fields or on deserialization unclear targets and it rightly warns about it.
    But the entry problem is not related to that.
     
  9. yehiaserag

    yehiaserag

    Joined:
    Mar 8, 2018
    Posts:
    6
    Is there a way to tell unity to "suppress" when extended?