Search Unity

SerializeReference Attribute?

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

  1. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    484
    Can someone please clarify the following: if a member (a custom serializable type) of a ScriptableObject asset is serialized by reference, should the non-serializable members persist values between editor play mode sessions? Like, imagine the following ScriptableObject:

    Code (CSharp):
    1. public class Container : ScriptableObject
    2. {
    3.     [SerializeReference]
    4.     public List<Item> Items;
    5. }
    And `Item` as follows:

    Code (CSharp):
    1. [System.Serializable]
    2. public class Item
    3. {
    4.     public string Value { get; set; } = null;
    5. }
    I've thought, that `Value` property of `Item` could never be serialized and persist values, as the properties can't be serialized by Unity, but in practice `Value` actually persist any value that is assigned to it at play mode; eg, on first play it has `null`, then I assign to it during play mode, exit play mode, enter play mode again and it still has the value assigned previously during play mode.

    I've made a reproduciton project and sent a bug request (Case: 1213759), but got a response, that this behavior is by design. I'm really confused now, as this breaks all the rules Unity previously had for serialization. Will really appreciate if someone form the devs team could clarify this. @alex-abreu-unity @LeonhardP @karl_jones @jasonm_unity3d @superpig
     
  2. elseforty

    elseforty

    Joined:
    Apr 3, 2018
    Posts:
    198
    kyuskoj likes this.
  3. kyuskoj

    kyuskoj

    Joined:
    Aug 28, 2013
    Posts:
    31
    Hi. I have 2 questions.

    1. Empty class(no field) instances in [SerializeReference] field are not deserialized and it becomes null when I back from prefab mode. Is this by design?

    I pushed a dummy data to make it work.
    Code (CSharp):
    1.  
    2. [Serializable] public class StartFsmCommand : ICommand
    3. {
    4.     [HideInInspector] public int dummy;
    5.  
    6.     public void Execute(object target) {};
    7.     public void Undo(object target) {};
    8. }

    2. [SerializeReference] attribute serializes a custom class which has no [Serializable] attribute. Is it intended?
     
    Last edited: Feb 7, 2020
    Hyp-X likes this.
  4. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,825
  5. NWHCoding

    NWHCoding

    Joined:
    Jul 12, 2012
    Posts:
    866
    I am glad to see that 2019.3.1f1 fixed [SerializeReference] list using wrong PropertyDrawer for its elements.

    The issue that was introduced is:
    - Editor is extremely slow when drawing a ReorderableList that has [SerializeReference] attribute.
    - Game mode is not usable when ReorderableList above is visible in the inspector window.

    This was not an issue in 2019.3.0f6 and no code was changed in the meantime.
    Should I submit a bug report or is this a known issue?

    Also, here are deep profiler results (performance is bad when moving an element but also when doing nothing):
    upload_2020-2-13_11-41-21.png

    It seems that DoList() takes a lot of time.
    Here is what is being drawn:
    upload_2020-2-13_11-42-34.png

    And a video:


    Worked perfectly smoothly in previous version and the rest of the inspector works great - only the reorderable list causes massive slowdowns.

    EDIT: Even with one element in the list with a bool and float field it is still noticeably slow.

    EDIT2: Submitted this as a bug, case: 1219277

    EDIT3: Non-SerializeReference list performance is normal. <= Ignore that, it is also much slower than before and shows lag when more elements are added.
     
    Last edited: Feb 14, 2020 at 1:04 PM
    TextusGames likes this.
  6. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    249
    Prefab instance bug.

    Instances of prefab
    are not serializing the type of field with serialized reference attributes. (the field is not marked as an override)
    After entering play mode the field type reverts back to type that is assigned in the prefab.
    It does, however, serialize changes made inside child fields ( if field type of instance is the same as in prefab). ( But after change made and the field was marked as an override, It still is not saved and after entering playmode reverts back to prefab field type).

    Noticeably clicking apply all overrides applies overrides to prefab as expected.

    @LeonhardP Is this a known bug?

    Edited.
    It appears it is a known limitation.
    https://forum.unity.com/threads/can...ereference-fields-in-prefab-instances.776669/

    It is kind of a shame because you use polimorfism to override behaviours. And prefab instance can be overriden too, but they are sadly not compatible for now.

    Edited.
    I was hoping may be prefab variants can override type of serialized reference atribute. But it still resets back..
     
    Last edited: Feb 14, 2020 at 6:30 AM
    kyuskoj, phobos2077 and NWHCoding like this.
  7. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    249
    Nasty renaming bug...

    Renaming used child type will set all your fields of parent type with serialized reference to null. And console will be throwing errors like this " Unknown managed type referenced: [AmimalWorld].Bird ".

    Renaming child class back does not restores data. So renaming a child class that was used at least in one field will loose all your data even in fields there it was not used....

    How are we supposed to rename child types that are used in fields with [SerializeReference]?
    How do you plan to support child class renaming?

    @LeonhardP Is this a known bug?
     
    Last edited: Feb 14, 2020 at 5:28 AM
  8. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    249
    I have a very extreme slow down of inspector even if one field(with SerializeREference attribute) is presented in deeply nested class that is in arrays (and the array is not marked as a serialized reference just one field in youngest child class).
    It is so slow even for 10 elements, that the unfolding variable can take 5 seconds.
    In (2019.3.1f1).

    Edited.
    I can confirm that this is a regression in 2019.3.1.f1 from 2019.3.0.f6.
    In 2019.3.0.f6 inspector is not slow at all.
     
    Last edited: Feb 16, 2020 at 9:16 PM
  9. NWHCoding

    NWHCoding

    Joined:
    Jul 12, 2012
    Posts:
    866
    ReorderableList for normal, non-SerializeReference lists, became extremely slow for me.

    The release of my asset hinges on this and Unity has been promising to fix SerializeReference for quite some time. I am starting to worry that they are out of their depth with SerializeReference in general - or at least out of testing personnel.
     
  10. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    249
    Since the [SerializeRference] is far from production-ready we need a thread for feedback.
    2019.3 beta thread is in the archive and not immediately visible for new users.
    Can someone move this thread into 2020.1 alpha/beta (since it is not archived and visible)?
    And old and new users can continue to gather feedback on this exiting feature.

    @alex-abreu-unity @LeonhardP @karl_jones @jasonm_unity3d @superpig
     
    kyuskoj and SonicBloomEric like this.
  11. Frantasad

    Frantasad

    Joined:
    Oct 25, 2018
    Posts:
    1
    For me the performance hit is sometimes realy HUGE.

    For example: I have small custom inspector for my questing system, and i used there only ReorderableLists and some propertydrawers. Here "Objectives" is just list of abstract objects of type Objective, there are only 4 derived types.
    When i tried to draw them in default array drawer i could not even write in the texfields. so i chached some properties and updated them only when necessary, but performance was still quite big (when writing delay between writed letters around 1sec).

    So now i am using reoderable set, (for Lists of abstract fields its rly usefull when u use dropdown for adding elements (as shown in image)) and i only show the description of objective and the selected one is drawn under the list.
    In the picture Quests are handled the same way even tho Quests are just SerializeField.

    I am caching everything here... for objectives i am drawing only one property (the actualy selected objective)
    and that property is changing only in callbacks of reorderableList.

    Still my performance here is slow as hell. But weird is that it depends on actual type of property.
    Here if Objective is AreaDetection (meaning AreaDetection derives from objective) then performace is like 4 times slower than if it is of type Interaction. (funny is that u can see that its that slow, if i write in description field, one letter shows up every 1 sec for Area and 1/4 of second for Interaction)

    And it does not depend on which quest i select, performance depends only on actual type
    Just to be clear, this is just my playing around with SerializeReference, i used to have only one class Objective where i held an enum of what kind of objective it was and i really did not like it, i am used to OOP, so i tried it here knowing polymorphism feature of SerializeReference.

    When i tried my old implementation of Objective with SerializeField on list of objectives, then performance is fine.
    Like totaly fine i mean, no lag at all.


    Screen.png

    Could i be doing something wrong ? Or is SerializeReference rly THIS MUCH SLOW ?
    i can share my code if you would like.
     
    Last edited: Feb 16, 2020 at 10:10 PM
unityunity