Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

SerializeReference Attribute?

Discussion in '2019.3 Beta' started by SonicBloomEric, May 15, 2019.

  1. jasonm_unity3d

    jasonm_unity3d

    Unity Technologies

    Joined:
    Mar 2, 2017
    Posts:
    41
    as of today, there are no plans for it that I am aware of.
     
  2. jasonm_unity3d

    jasonm_unity3d

    Unity Technologies

    Joined:
    Mar 2, 2017
    Posts:
    41

    yes, just add [SerializeReference] to public List<Animal> animals;
     
    Novack likes this.
  3. jasonm_unity3d

    jasonm_unity3d

    Unity Technologies

    Joined:
    Mar 2, 2017
    Posts:
    41
    That sounds a like a bug, please log an issue so that we can track it and resolve it asap. thanks!

    https://unity3d.com/unity/qa/bug-reporting
     
  4. taylank

    taylank

    Joined:
    Nov 3, 2012
    Posts:
    182
    Experiencing the same thing. And the editor crashes every other minute when trying to work with this feature.
     
    CyrilGhys likes this.
  5. stopiccot_tds

    stopiccot_tds

    Joined:
    Oct 1, 2016
    Posts:
    111
    Do you plan guys to add support to serialize template classes without declaring specialized type?
    Code (csharp):
    1. [Serializable]
    2. public class TemplateClass<T>
    3. {
    4.     public T val;
    5. }
    6.  
    7. [Serializable]
    8. public class TemplateClassInt : TemplateClass<int> { }
    9.  
    10. public TemplateClass<int> intClass1;
    11. public TemplateClassInt intClass2;
    intClass1 is not shown in the inspector
     
    Prodigga likes this.
  6. jasonm_unity3d

    jasonm_unity3d

    Unity Technologies

    Joined:
    Mar 2, 2017
    Posts:
    41
    At the moment, there are no plans to support generics.
     
  7. jasonm_unity3d

    jasonm_unity3d

    Unity Technologies

    Joined:
    Mar 2, 2017
    Posts:
    41
    please log bug reports so that we can address instabilities. thank you.
    https://unity3d.com/unity/qa/bug-reporting
     
  8. FabioFZynga

    FabioFZynga

    Joined:
    Sep 24, 2018
    Posts:
    8
    The doc link is broken, and searching for SerializeReference in the Manual or Scripting API pages for 2019.3 returns no results :/
     
  9. FabioFZynga

    FabioFZynga

    Joined:
    Sep 24, 2018
    Posts:
    8
    This looks beautiful! I've tried it out (exact same code) in Unity 2019.3.0a11, the Trees field appears in the Editor but it is broken! (just shows a list of labels with no ability to add or edit anything) Is that normal?
     
  10. AndrewKaninchen

    AndrewKaninchen

    Joined:
    Oct 30, 2016
    Posts:
    149
    Might I ask why? It really bothers me, as even Unity falls into this trap from time to time. Addressables and UnityEvents, for example, have clunky workarounds because of that. And we know it is possible from a usability standpoint. Odin Serializer is very much capable of working in tandem with Unity's serializer where the second can't, so I can't imagine why Unity's serializer couldn't use a hybrid approach to it, even if using the current way to do it is theoretically impossible. You'd just have to do it a different way wherever it is required.

    Using generics in Unity is a nightmare the way it currently works (as in, it doesn't). In my last project I had to do so many workarounds to be able to serialize everything I needed that in the end I just gave up and refactored everything to go with Odin Serializer so my code could look like it should.
     
  11. stopiccot_tds

    stopiccot_tds

    Joined:
    Oct 1, 2016
    Posts:
    111
    Such a shame in 2019...
     
  12. mykillk

    mykillk

    Joined:
    Feb 13, 2017
    Posts:
    60
    This usage case is very close to what I am using this for. However, I could not get it to work at first. The elements in m_Trees were serializing references correctly, but the [SerializeReference] fields in the derived classes were not being serialized at all.

    My Node class did not derive from anything, so noticing that in this example the base class was an interface I tried doing that and converting all my references in the derived classes to interface references. Then all the serialization worked as I had hoped!

    Is it really the case that a class can't serialize its own type reference? It's not a problem to add the extra interface but I was wondering why using an interface "middle-man" makes this work.
     
    Last edited: Aug 10, 2019
  13. jasonm_unity3d

    jasonm_unity3d

    Unity Technologies

    Joined:
    Mar 2, 2017
    Posts:
    41
    You are saying that:

    Code (CSharp):
    1.  
    2. class Node
    3. {
    4.   [SerializeReference] public Node left;
    5.   [SerializeReference] public Node right;
    6. }
    7.  
    8. class SpecialNode : Node
    9. {
    10.   [SerializeReference] public object extraData;
    11. }
    12.  
    13. class Tree: MonoBehaviour
    14. {
    15.     [SerializeReference] public Node Root;
    16. }
    17.  
    that a tree with a node of type
    SpecialNode
    does not serialize
    extraData
    , unless interfaces are used to abstract the Node type?

    if that is the case, then it's a bug. please report it so that we can track it and fix it.

    thanks,
    -J
     
  14. mykillk

    mykillk

    Joined:
    Feb 13, 2017
    Posts:
    60
    Actually what I was seeing is that in your example, Root would serialize fine, but left and right would not. I'm not sure about extraData, but it probably would. It only seems to be self-referencing type fields that have the issue. Adding an "INode" interface to the Node class and changing left and right fields to be of INode type would get it to serialize correctly.
     
  15. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,085
    A quick sanity check here: all class definitions in your hierarchy are marked with the [System.Serializable] attribute, yes?
     
  16. mykillk

    mykillk

    Joined:
    Feb 13, 2017
    Posts:
    60
    Here is a concrete example with results.

    With the code set up like:
    Code (CSharp):
    1. public interface IFlowNode { }
    2.  
    3. [System.Serializable]
    4. public class FlowNode : IFlowNode
    5. {
    6.     public FlowNodeId Id;
    7.     public FlowChart Chart;
    8.     public FlowSegment Segment;
    9.     [SerializeReference] public IFlowNode Next;
    10.     [SerializeReference] public IFlowNode Prev;
    11.     public FlowRunMode RunMode;
    12.     public FlowRunClause RunClause;
    13. }
    It serializes the references correctly. Here is the serialized output to the .asset file:

    00000001:
    type: {class: FlowNode, ns: PF.Core, asm: Assembly-CSharp}
    data:
    Id:
    Index: 0
    Revision: 0
    Chart: {fileID: 0}
    Segment: 0
    Next:
    id: 6
    Prev:
    id: 5
    RunMode: 0
    RunClause: 0


    However, with the code set up like:
    Code (CSharp):
    1. [System.Serializable]
    2. public class FlowNode
    3. {
    4.     public FlowNodeId Id;
    5.     public FlowChart Chart;
    6.     public FlowSegment Segment;
    7.     [SerializeReference] public FlowNode Next;
    8.     [SerializeReference] public FlowNode Prev;
    9.     public FlowRunMode RunMode;
    10.     public FlowRunClause RunClause;
    11. }
    The serialized result completely ignores the FlowNode fields:

    00000001:
    type: {class: FlowNode, ns: PF.Core, asm: Assembly-CSharp}
    data:
    Id:
    Index: 0
    Revision: 0
    Chart: {fileID: 0}
    Segment: 0
    RunMode: 0
    RunClause: 0
     
    Last edited: Aug 24, 2019
  17. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,646
    Supported in 2020.1.0a2.
     
  18. Wow! I am waiting for this feature for my personal framework forever. Do you have a time machine which is going forward in time faster than the standard 1 second per second rate? I want to be in 2020 today. :)
     
    Alverik and Prodigga like this.
  19. AndrewKaninchen

    AndrewKaninchen

    Joined:
    Oct 30, 2016
    Posts:
    149
    Nice
     
  20. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    That is great! How does this work with custom editors?
     
  21. starikcetin

    starikcetin

    Joined:
    Dec 7, 2017
    Posts:
    340
  22. stopiccot_tds

    stopiccot_tds

    Joined:
    Oct 1, 2016
    Posts:
    111
    I guess that would be even bigger Unite announcement than nested prefabs)
     
  23. kvfreedom

    kvfreedom

    Joined:
    Mar 30, 2015
    Posts:
    37
    If the class name changes, the reference will be lost. Is it possible to store by GUID instead of the class name.
     
    JesOb likes this.
  24. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    Woah. Does it mean this is going to work?
    Code (CSharp):
    1. public UnityEvent<int> eventWithAnInt;
    I have like thirty wrapper classes for UnityEvent since I can't use it directly with template arguments in the inspector.
     
    Last edited: Aug 28, 2019
    Prodigga likes this.
  25. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,123
    I am late to the party but wanted to chime in and say this is excellent news! Kicking goals, Unity serialisation team! :) I assume DoctorShinobi's case would be supported by this? Could we get a confirmation?

    I have similar use cases - a generic class that I need to inherit every time just to specify the type so it is serializable.

    Can the type T be any type, or are there limitations? Would it work fine if T was GameObject, or MonoBehaviour? Or must it be a plain old serializable class?
     
  26. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    I would hazard a guess that if manually specializing it works, then leaving it in its raw generic form will work @Prodigga
     
  27. ObelardO

    ObelardO

    Joined:
    Feb 20, 2015
    Posts:
    3
    Code (CSharp):
    1. Generating diff  of this object for undo because the type tree changed.
    2. This happens if you have used Undo.RecordObject when changing the script property.
    3. Please use Undo.RegisterCompleteObjectUndo
    Everytime when i trying to record object with [SerializeReference] attribute.
     

    Attached Files:

  28. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
  29. merpheus

    merpheus

    Joined:
    Mar 5, 2013
    Posts:
    202
    Is that also mean that, there could be a Dictionary serialization support in 2020.1 ?
     
  30. arkogelul

    arkogelul

    Joined:
    Nov 14, 2016
    Posts:
    105
    Hi all,

    I'm trying to figure out why this thing is that massive. Could someone explain why is it a great thing ?
    I'm kind of new to C# and Unity, but if I can learn something to improve, I'll go for it !
     
  31. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    Probably not, they're quite unrelated issues
     
    merpheus and Prodigga like this.
  32. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,909
    It's for when you need to save/load data. If you use OOP features such as inheritance (to store many different Types in the same list, for example) you cannot easily save the data to a file. It will only save the serializable fields (strings, ints, etc) data of the base class and ignore the data from the children. This means you have to make an entirely different "saveable" or simplified version of each class (or use a better serializer system), which is harder when there are references to other things, because you will need a unique ID of some kind.

    It looks like when SerializeReference is bug-free, I will just be able to put it on my class and it will save/load perfectly.

    The best way to see serialized data is by making a ScriptableObject with some public fields, then you can open the asset in notepad, and see the data that was saved as YAML at the bottom.
     
  33. arkogelul

    arkogelul

    Joined:
    Nov 14, 2016
    Posts:
    105
    Thank you for the explanation :)
    It doesn't fully make sense, but it gives me an idea. We didn't tackle the save/load system yet, but I'll definitely check this out. Where can I find further information on the subject ?
     
  34. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,085
    Google is your friend.

    But here are some resources:
    All of the above strongly point out that you cannot type serialized fields using Interfaces, Abstract Classes, or a base class as the current serializer has zero support for it. This is why things like Odin exist and why everyone is so excited that Unity finally added support for some of the missing serialization features.
     
    Alverik, a436t4ataf and arkogelul like this.
  35. Yuri-b

    Yuri-b

    Joined:
    Apr 16, 2017
    Posts:
    1
    I'm experiencing an issue when duplicating/cloning the object. The references of the polymorphic object ([SerializeReference]) that refer to the game object or its components being duplicated are not updated. For instance when I duplicate a game object with a script named Foo that has a property holding the value of type Bar (serialized POCO) and it holds a reference to the game object being duplicated (Foo.bar.gameObject = Foo.gameObject) I end up with two scripts referring to one game object. When object is serialized by value ([SerializedField]) the references to the objects are properly copied/updated.
    I hope this is something that will be changed/fixed in future releases? Otherwise the feature is quite useless.
     
    chadfranklin47 likes this.
  36. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,203
    Please file a bug report so we can make sure this is addressed.
     
  37. Ramobo

    Ramobo

    Joined:
    Dec 26, 2018
    Posts:
    212
    But why? What in the design of the serialization system causes this deal-breaker? For a lot of people, I'm assuming. All that the assumed people and I need out of this feature is to be able to serialize a field that takes a MonoBehaviour that implements a specific interface.
     
    ElasticSea, CyrilGhys, Nefahl and 3 others like this.
  38. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,039
    +1
     
    jyfc likes this.
  39. QFSW

    QFSW

    Joined:
    Mar 24, 2015
    Posts:
    2,906
    If I had to guess, most likely how it instantiates the classes on deserialization; using the method that every other class uses wouldn't work for UnityEngine.Object

    Granted, I don't see why they don't just add a custom factory that uses the AssetDatabase for UnityEngine.Objects, but who knows, there may be something I'm not seeing
     
    Alverik and Ramobo like this.
  40. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    1,085
    Guessing here, myself, but I think you're basically right. The added complication is that UnityEngine.Object references are properly restored, whereas POCOs are duplicated wherever a single reference was originally shared. To handle this guarantee in the serialization system would likely require additional metadata and, thus, changes to the serialization format itself. I'd be willing to bet that the code to serialize UnityEngine.Objects is both more complex and far deeper in the codebase and isn't something they are interested in touching...
     
    Alverik and QFSW like this.
  41. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,924
    It's for much, much more than that! (hint: the entire Editor is implemented via Serialization. Typically merely clicking things in the Inspector, or selecting objects, will break without correct Serialization).

    ...hence the huge excitement. This takes a lot of code that is correct C#, but bizarrely corrupts/breaks/decouples itself when running in Unity (and at unpredictable moments), and makes it Just Work. The traditional workaround has been to "write lower quality C# code (that avoids using many of the most important features of the C# language, because they break Unity)" or "write huge amounts of complex workarounds / buy complex workarounds from the asset store".
     
    Alverik likes this.
  42. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    809
    Piggybacking on this: after a reserialization of foo1, would foo1.boo still point to the same object reference or would it be a new object?

    In other words:

    Code (CSharp):
    1.  
    2. void SomeMethodSomewhere( GameObject go )
    3. {
    4.     var foo = go.AddComponent(typeof(Foo)) as Foo;
    5.     var booBefore = foo.boo;
    6.     // Reserialize foo somehow
    7.     var booAfter = foo.boo;
    8.  
    9.     Debug.Log(booBefore == booAfter); // True or false?
    10. }
    11.  
    If this outputs true, then I have a million other questions. ;):rolleyes:
     
  43. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    279
    I'm also a bit disappointed to see that this doesn't let you serialize UnityEngine.Object via their interface.

    UnityEngine.Objects are already serialized by reference. Would it be possible to treat all public/serializable interface fields as a field that can only serialize UnityEngine.Object? The SerializeReference attribute could then be used to differentiate between the intent to serialize POCOs or UnityEngine.Object
     
    sirxeno likes this.
  44. I_Jemin

    I_Jemin

    Joined:
    Jul 31, 2014
    Posts:
    11
    Is there plan to add this feature in Unity 2018.4? I really love and need this but company I working with won't change the unity version :(
     
  45. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    Not going to happen, unless they break their own rules:
    https://unity3d.com/unity/qa/lts-releases
     
    Last edited: Oct 1, 2019
    Alverik, superpig and karl_jones like this.
  46. mykillk

    mykillk

    Joined:
    Feb 13, 2017
    Posts:
    60
    So what's the opinion on this? Is this a bug that I should report or is this expected behavior?

     
  47. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,203
    Yes please file a bug report.
     
  48. mykillk

    mykillk

    Joined:
    Feb 13, 2017
    Posts:
    60
    Ok just submitted my bug report.

    EDIT: Will post case ID number when emailed to me.
     
    Last edited: Oct 8, 2019
  49. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    970
    @karl_jones So, finally got to use this for some tooling, but unfortunately I very quickly run into an 100% reproducible crash, along with some general oddity. Case 1189933 (@LeonhardP)

    Basically, when serialising an array of polymorphic objects marked with SerializeReference, if one of those objects contains an array stability goes out the window.

    In the most basic form, if I have two objects, the first of which has a primitive field and the second of which has an array field of a primitive, once I add any elements to that array, editing the primitive field crashes the editor 100% of the time.

    Sometimes it will also get in a weird situation where editing the array elements themselves gets incredibly slow and then the editor locks up in a native-side infinite loop. Annoyingly, I stopped being able to reproduce this and lost the call stack of where it gets stuck but it's somewhere related to SerializedProperty::GetStringValue() and it looks like it's copying strings in an infinite loop.
     
    Last edited: Oct 8, 2019
    LeonhardP and karl_jones like this.
  50. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    Can you please post the bug-report case number (number only, not the link) here for Unity staff to pick up.