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

SerializeReference Attribute?

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

  1. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    I noticed that the issue is now marked as fixed in 2021.1.0a5, so I tested it and the constructors of the serialized objects are now invoked as expected, but the property initializers are still ignored (values are lost) when entering play mode. I've also noticed that the title of the issue has been changed and it's no longer mention the field initializers. I've submitted another issue (Case 1293793) with the repro; really hope it'll eventually be fixed in 2019.4 LTS.



    @karl_jones @LeonhardP @unity_Etienne @alex-abreu-unity @MartinBarrette
     
  2. MartinBarrette

    MartinBarrette

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    26
    The issue which you are observing, is due to the backing field of the property being serialized in the editor to display those in the debug inspector. This is inconsistent as we are not serializing backing fields elsewhere currently. We will address this in the short term likely by disabling the support for backing field in the editor.
     
    oscarAbraham, Elringus and karl_jones like this.
  3. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    Thank you for the response! I was able to reproduce the same issue with private fields, though; I've shared the details in the email, so I guess it'd be better to continue the conversation there.
     
  4. MartinBarrette

    MartinBarrette

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    26
    The reason that backing fields are serialized is to enable hot reloading of script during play mode. This is also the case for private fields as documented https://docs.unity3d.com/Manual/ConfigurableEnterPlayModeDetails.html step 3b. Changing the behavior would have impacts on lots of existing users. The workaround is to use [NonSerialized] to explicitly prevent the serialization of the content of those fields when entering play mode.
     
    phobos2077 likes this.
  5. fwalker

    fwalker

    Joined:
    Feb 5, 2013
    Posts:
    255
    But you still can NOT do this can you?
    The interface if showing the lable of the field "doable". But no box to drop a reference in

    Code (CSharp):
    1.  
    2. public interface IDoable {
    3. void DoIt();
    4. }
    5. public class Doer : MonoBehaviour, IDoable {
    6. public void DoIt(){};
    7. }
    8. public class Doer2 : MonoBehaviour, IDoable {
    9. public void DoIt(){};
    10. }
    11.  
    12. public class DoableContainer : MonoBehaviour
    13. {
    14.     [SerializeReference]
    15. public IDoable doable;
    16. }
     
    Last edited: Nov 24, 2020
  6. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    Try this.
    Code (CSharp):
    1.  
    2. public interface IDoable {
    3. void DoIt();
    4. }
    5. public class Doer : MonoBehaviour, IDoable {
    6. public void DoIt(){};
    7. public int i;
    8. }
    9. public class Doer2 : MonoBehaviour, IDoable {
    10. public void DoIt(){};
    11. }
    12.  
    13. public class DoableContainer : MonoBehaviour
    14. {
    15.     [SerializeReference]
    16. public IDoable doable = new Doer();
    17. }
    You should see the instance of Doer to the right from the label.

    But you right you can not change reference in editor with just unity default tools.

    To change references in editor you can
    use Odin Inspector
    or https://forum.unity.com/threads/serializereference-genericserializedreferenceinspectorui.813366/
    or create your own changer - drawer
    or convince Unity to implement that must needed feature :)
     
    chunky_octopus likes this.
  7. Elringus

    Elringus

    Joined:
    Oct 3, 2012
    Posts:
    483
    I see, thank you for the clarification! I've also noticed that making the field `readonly` excludes it from the serialization as well. Is that something we can rely on or [NonSerialized] attribute is the only proper way to do this?
     
  8. vertxxyz

    vertxxyz

    Joined:
    Oct 29, 2014
    Posts:
    109
    When using SerializedProperty is it possible to let DuplicateCommand or
    InsertArrayElementAtIndex to function as they previously did, where it actually duplicates the value?
    The current (and apparently intended) behaviour is that it duplicates by reference.

    I really don't want to have to find the field via reflection, duplicate that with a serializer, and then set that back. I have that code, it's just very unnecessary seeing as all the data is here and waiting. There just seems to be no API to do it, unless I'm missing something?
     
    Ghat-Smith and JesOb like this.
  9. RecursiveEclipse

    RecursiveEclipse

    Joined:
    Sep 6, 2018
    Posts:
    298
    Is there no way to serialize a System.Type with this? If I try to assign a type in a property drawer to property.managedRefeferenceValue it gives NotSupportedException from somewhere in the RuntimeType constructor.(It doesn't actually give me a proper traceback)
     
  10. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hi, this might be of interest to people watching this thread. When the issue of instances being recreated was marked as fixed (https://issuetracker.unity3d.com/is...lds-lose-their-values-when-entering-play-mode), I was very happy and I tested it a lot. It works relatively well for me, except that instances are still recreated on Undo/Redo.

    I've just noticed that Unity devs were able to reproduce the bug and added it to the issue tracker. Here it is in case anyone wants to follow or vote on it: https://issuetracker.unity3d.com/is...difiying-any-field-and-then-doing-ctrl-plus-z
     
    TextusGames likes this.
  11. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    542
    Im using 2019.4.17f1 and noticed something weird. I have a ScriptableObject with a [SerializedReference] List<SomeAbstractType>, some of these derived Types contain a enum.
    I wrote a custom editor to add instances to the list in the inspector.

    Now the weird thing is that the new inserted instance shows all enum fields as number instead of a string value, but if I click somewhere else in the editor and reselect the ScriptableObject asset it suddenly shows the enum members as strings again.

    Does anyone know if there is some way to force the same logic a focus change does, to show the string values directly after my add item logic? I tried to call the Repaint() method of the editor, but it didn't help, only a real focus change seems to work.
     
    Last edited: Jan 12, 2021
    Ghat-Smith likes this.
  12. MartinBarrette

    MartinBarrette

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    26
    If you use https://docs.unity3d.com/ScriptReference/SerializedProperty-managedReferenceValue.html to insert those new instances the fields will show up as Enum. We have fixed an issue related to this which will be backported in older versions.
     
    Ghat-Smith, R1PFake and karl_jones like this.
  13. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    542
    Thanks for the hint, I can confirm that it works with my custom editor by setting the managedReferenceValue instead of adding directly to the list
     
    MartinBarrette likes this.
  14. Yany

    Yany

    Joined:
    May 24, 2013
    Posts:
    96
    Actually the SerializeField issue still exists: https://issuetracker.unity3d.com/is...leting-last-array-item-and-then-pressing-undo

    It sounds like it's a separate problem, but in the notes of the issue down below you can see that's the same it was discussed last year(!): "When deleting array element Editor throws this error: Could not reach source property name 'entries.Array.data[0]' while extracting diffs, the reference does not exist in the source serialized data"

    So it's not an UNDO issue. Could you press a vote on it please? Thank you.
     
    Last edited: Feb 2, 2021
    oscarAbraham likes this.
  15. MartinBarrette

    MartinBarrette

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    26
    https://issuetracker.unity3d.com/is...642718.95653275.1612321609-6940258.1548978882
    FYI this issue has been fixed locally and the fix is being reviewed and validated currently.
     
    Yany, oscarAbraham and TextusGames like this.
  16. Yany

    Yany

    Joined:
    May 24, 2013
    Posts:
    96
    That's very good news, thank you.
     
  17. manetageorge

    manetageorge

    Joined:
    Sep 9, 2020
    Posts:
    4
    Don't know if this is a bug, but a [SerializeReference] property inside a [SerializeReference] property comes out as a SerializedProperty with Generic propertyType, and not the expected ManagedReference type.

    This makes it impossible to set the managedReferenceValue of the inner property (throws InvalidOperationException) in a custom property drawer. Pls help.

    upload_2021-3-12_18-51-42.png
     
    japtar10101 likes this.
  18. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hi, sorry for the necropost. If you have some time, I'd really appreciate if you could share some info:

    Did you ever see this error fixed? I still see it present; it seems to happen with managed reference that contain a serialized struct or class (such as Vector3). Specifically, it happens every time such a reference takes the place of another that has a field with the same name but different type when changing a list size.

    I don't understand what's the relationship between this bug and the one about references being recreated. Also, that bug is fixed, but this one is not. Did they tell you some explanation?

    I'll probably submit a bug report with what seems to be the same exact bug that remains unfixed. I'd like to avoid it marked as Duplicate again or as By Design, or fixed only partially, so I'd really appreciate it if you have any info that you think could help to make my report as clear as possible.

    Thanks a lot for your time. Best Wishes :)
     
  19. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    To be honest I didn't check if it was fixed, until today. I never again used SerializeReference attribute from that time, becuase it looked like endless batally - when bug1 get fix, there is another bug2, but it needs bug3 to be fixed, then they say it was fixed, but bug1 still persist and there is another bug99.

    I originally reported this bug 14 april and I got answer 5 june, that they can't reproduce issue.
    I had to attach video and then they managed to do it and this issue was made, but not as duplicate.
    10 days later I got this:
    That issue was resolved for so long that I forgot to check if my problem was solved.
    I done test moment ago in unity 2020.3.4 - sadly there is exactly the same issue as it was 1 year ago.o_O

    They said "send email in case the issue still exists", so I will send email in a moment. I will post if I get answer.
     
  20. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hey, thank you very much. I hope they can see it happens with fields that have the same name but a different compound type. Sometimes it seems things get lost in translation between QA and the people that fix bugs, so things get stuck; but they still have the best intentions to fix issues, in my experience. I'll stay posted then for their response. I'll try to supply additional info/examples if it's necessary.

    Thanks for sending the email and looking at this. I really appreciate it. I hope you have a great day.
     
    phobos2077 and Qriva like this.
  21. Alex-Chouls

    Alex-Chouls

    Joined:
    Mar 24, 2009
    Posts:
    2,663
    I'm still seeing this issue in Unity 2020.2f1 even though it's marked fixed:
    https://issuetracker.unity3d.com/is...ts-lose-its-data-when-a-class-name-is-changed

    From the comments it seems like other people are too. It would be fine if it lost the data for the changed class, but instead it loses all its data! This makes the whole system feel terribly fragile and is a showstopper for me, which is a shame because its wonderful when working properly, massively simplifying a lot of code.

    What's the mechanism to re-open this bug?
     
    Ghat-Smith and phobos2077 like this.
  22. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hi. I just tested this in 2020.3 and didn't see any data loss, neither when I rename a root class or any of its children. That said, I'm not discounting your experience; I've seen some pretty weird bugs related to [SerializeReference] that I can't reproduce consistently. I've been weary of using this too much, or on cases that seem too complex for this reason.

    Still, this might help you: When a managed reference class is missing, the Object can't be saved anymore, and all the managed references are temporarily set to null. Maybe this seems like data loss? I guess some of this behavior is actually to prevent data loss; data can't change permanently until Unity is able to make sense of it. The moment the missing class or another with the proper UnityEngine.Scripting.APIUpdating.MovedFromAttribute appears, things can be edited again, and the old data becomes visible. That attribute is suggested as a workaround in this related issue: https://issuetracker.unity3d.com/is...e-data-lost-when-the-class-name-is-refactored.

    Could it be that? Does data reappear when the missing class reappears?
     
    Last edited: Apr 24, 2021
  23. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hey! I saw the issue has been reopened :). Thanks for telling them that the issue still exists. I found a workaround in case it helps:

    I saw that the issue doesn't only appear when adding or removing elements from a list, it also appears when using SerializedProperty.MoveArrayElement. I got curious because Unity's own reorderable list doesn't trigger that error, so I looked at their implementation and I saw that using RegisterCompleteObjectUndo prevents the error from happening.

    So, if you're okay with doing some more editor shenanigans, deleting like this doesn't print the error:
    Code (CSharp):
    1. Undo.RegisterCompleteObjectUndo(targets, "Remove managed reference");
    2. listProp.DeleteArrayElementAtIndex(index);
    3. serializedObject.ApplyModifiedPropertiesWithoutUndo();
     
  24. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    Actually possible that after I wrote the email it opens automatically (but not sure) - I haven't received an answer yet.

    About workaround, I hope it is just editor problem, but currently I can't remember if something similar didn't happen in runtime.
     
  25. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Oh, you're right. I forgot it reopens automatically :/. Still, thanks for telling them.

    I wouldn't worry a lot. I've been using this quite a bit and I haven't seen something related to this bug at runtime. It only happens when registering with the editor's Undo. Also, even in the editor, there doesn't seem to be any data corruption; I'm not completely sure it can't happen with ctrl+z, though. I hope they fix it, because it quickly fills the console with garbage, but this workaround will do it for me in case they don't or take too long; SerializeReference usually requires custom editors to be usable, anyway.
     
  26. kvfreedom

    kvfreedom

    Joined:
    Mar 30, 2015
    Posts:
    37
    https://issuetracker.unity3d.com/is...e-data-lost-when-the-class-name-is-refactored
     
  27. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    @oscarAbraham Ok, there is reply about my issue.
     
  28. Alex-Chouls

    Alex-Chouls

    Joined:
    Mar 24, 2009
    Posts:
    2,663
    Yes that was it. The data reappears when the missing class is restored.

    UnityEngine.Scripting.APIUpdating.MovedFromAttribute also works. Thanks, I would never have found that attribute, and still can't find any documentation for it, but at least there's a workaround. Thanks again!
     
    oscarAbraham and phobos2077 like this.
  29. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    This is absurd. Sorry, I really know that other humans work there and human errors happens,
    but I feel like they simply don't treat me like human there.

    I clearly stated before that "I checked again in Unity 2020.3.4f1" and this error still exists and today, again I received this message:
    So, to confirm I am sane, I tested it again in 2019.4.18f1, but guess what! Error is still there xD

    Seriously, I understand they overlooked the issue for 1 year, but this time I was simply ignored, they didn't even bother to check anything, let's just pretend it's fixed. I feel a bit disgusted :(.
    And yes, I will write email again.
     
    phobos2077 and oscarAbraham like this.
  30. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Ugh:(. That's bad. I can imagine how frustrating it can be to be treated like that. Running your example for the bug would have taken very little time, and it seems common sense that you wouldn't have written again if the problem didn't persist. It's also common sense that an existing issue can't be a duplicate of a solved one. I'll submit another bug report in case it helps, I'll try to be very thorough, and I'll link to these posts.

    I'm sorry you've been embroiled in this problem. I really hope this is just a misunderstanding; people in QA have usually been very nice in my experiences. I realize you said you weren't using SerializeReference anymore and you probably weren't even thinking of this issue. I'm very thankful to you for taking care this issue, even though it doesn't affect you. You've been reallyy nice and I think you deserve better. I'll tell you when I get a response.
     
  31. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    I sent super clear message again, so I hope they will understand this time.
    I don't think it was made on purpose, but come on - linking to the same resolved issue second time? As you said I wouldn't even bother to write message if it worked...
    It is not like it does not affect me completely, I would like to use this attribute, but I don't want to do it because I know it still causes issues and looks like they don't want to fix it :D
     
    phobos2077 and oscarAbraham like this.
  32. Lynxed

    Lynxed

    Joined:
    Dec 9, 2012
    Posts:
    121
    I come to this thread every now and then with slight hope that i don't have to do ScriptableObject for every freaking node for my graphs again, and i could just use references like other coders.
    2021: nope. seems like i can't.
     
  33. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    So, after so much trouble. The issue was marked as "won't fix". The reason given is that SerializeReference doesn't support inflated generics. This error has nothing to do with generics. The code behind this example doesn't use inflated generics for the references; it uses concrete classes. Yes, they inherit from inflated generics, but they are not generic themselves by any standard definition. It's not what the documentation is talking about; and they don't cause the same errors as real inflated generics.

    Furthermore, the issue would happen even if the classes used didn't inherit from any class, as long as their fields have the same name. Here's a forum post behind this issue, in case anyone wants to see the code: https://forum.unity.com/threads/serializereference-attribute.678868/page-5#post-5674003

    :/ It's not a terribly important issue, but the way it's been wrongly dismissed three times is sad. I think I'll have to submit a bug report for the same issue with pure, simple, POCOs. :( I don't know what happened there; maybe it's because I'm now very familiar with the issue, and also I don't have direct access to the bug report, but the last two reasons given to dismiss it seem very clearly invalid, at plain sight, to me.

    EDIT
    I've made a bug report without using generics anywhere. This is the code used:

    Code (CSharp):
    1. [System.Serializable]
    2. public class CompoundObject
    3. {
    4.     public string Text1;
    5.     public string Text2;
    6. }
    7.  
    8. public abstract class Container { }
    9.  
    10. [System.Serializable]
    11. public class IntContainer : Container { public int data; }
    12.  
    13. [System.Serializable]
    14. public class BoolContainer : Container { public bool data; }
    15.  
    16. [System.Serializable]
    17. public class CompoundObjectContainer : Container { public CompoundObject data; }
    18.  
    19. [System.Serializable]
    20. public class VectorContainer : Container { public Vector3 data; }
    21.  
    22. [CreateAssetMenu]
    23. public class SRBugReproducer : ScriptableObject
    24. {
    25.     [SerializeReference] public Container SRField;
    26. }
    27.  
    28. [CustomEditor(typeof(SRBugReproducer))]
    29. public class SRBugReproducerEditor : Editor
    30. {
    31.     SerializedProperty m_fieldProp;
    32.  
    33.     private void OnEnable()
    34.     {
    35.         m_fieldProp = serializedObject.FindProperty("SRField");
    36.     }
    37.  
    38.     public override void OnInspectorGUI()
    39.     {
    40.         serializedObject.Update();
    41.         EditorGUILayout.PropertyField(m_fieldProp, true);
    42.  
    43.         DoProblemButtons();
    44.         EditorGUILayout.Space(22);
    45.         DoButtonsWithoutProblem();
    46.  
    47.         serializedObject.ApplyModifiedProperties();
    48.     }
    49.  
    50.     private void DoProblemButtons()
    51.     {
    52.         GUILayout.Box("1. ASSIGN A REFERENCE WITH A SIMPLE VALUE:", GUILayout.ExpandWidth(true));
    53.         using (var horizontalScope = new GUILayout.HorizontalScope(EditorStyles.toolbar))
    54.         {
    55.             if (GUILayout.Button("IntContainer"))
    56.                 m_fieldProp.managedReferenceValue = new IntContainer();
    57.             if (GUILayout.Button("BoolContainer"))
    58.                 m_fieldProp.managedReferenceValue = new BoolContainer();
    59.         }
    60.  
    61.         GUILayout.Box("2. ASSIGN A REFERENCE WITH A COMPOUND VALUE:", GUILayout.ExpandWidth(true));
    62.         using (var horizontalScope = new GUILayout.HorizontalScope())
    63.         {
    64.             if (GUILayout.Button("CompoundObjectContainer"))
    65.                 m_fieldProp.managedReferenceValue = new CompoundObjectContainer();
    66.             if (GUILayout.Button("VectorContainer"))
    67.                 m_fieldProp.managedReferenceValue = new VectorContainer();
    68.         }
    69.     }
    70.  
    71.     private void DoButtonsWithoutProblem()
    72.     {
    73.         GUILayout.Box("1. ASSIGN A REFERENCE WITH A SIMPLE VALUE", GUILayout.ExpandWidth(true));
    74.         using (var horizontalScope = new GUILayout.HorizontalScope())
    75.         {
    76.             if (GUILayout.Button("IntContainer"))
    77.             {
    78.                 //We use RegisterCompleteObjectUndo because RecordObject still causes the bug.
    79.                 Undo.RegisterCompleteObjectUndo(target, "Change Reference");
    80.                 m_fieldProp.managedReferenceValue = new IntContainer();
    81.                 //We apply without undo to avoid triggering the bug.
    82.                 serializedObject.ApplyModifiedPropertiesWithoutUndo();
    83.             }
    84.             if (GUILayout.Button("BoolContainer"))
    85.             {
    86.                 Undo.RegisterCompleteObjectUndo(target, "Change Reference");
    87.                 m_fieldProp.managedReferenceValue = new BoolContainer();
    88.                 serializedObject.ApplyModifiedPropertiesWithoutUndo();
    89.             }
    90.         }
    91.  
    92.         GUILayout.Box("2. ASSIGN A REFERENCE WITH A COMPOUND VALUE", GUILayout.ExpandWidth(true));
    93.         using (var horizontalScope = new GUILayout.HorizontalScope())
    94.         {
    95.             if (GUILayout.Button("CompoundObjectContainer"))
    96.             {
    97.                 Undo.RegisterCompleteObjectUndo(target, "Change Reference");
    98.                 m_fieldProp.managedReferenceValue = new CompoundObjectContainer();
    99.                 serializedObject.ApplyModifiedPropertiesWithoutUndo();
    100.             }
    101.             if (GUILayout.Button("VectorContainer"))
    102.             {
    103.                 Undo.RegisterCompleteObjectUndo(target, "Change Reference");
    104.                 m_fieldProp.managedReferenceValue = new VectorContainer();
    105.                 serializedObject.ApplyModifiedPropertiesWithoutUndo();
    106.             }
    107.         }
    108.     }
    109. }
     
    Last edited: May 25, 2021
    phobos2077 and Prodigga like this.
  34. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    Lets ignore the real problem, what's the actual definition of inflated type?
    From everything I have ever seen I concluded:
    Code (CSharp):
    1. MyConcreteClass : EvilGenericClass<int> // This is concrete class inheriting generic template
    2. EvilGenericClass<T> // This is generic class (and it will be inflated? if I put for example int inside T)
    Additionaly when I see something like this:
    I am even more convinced that I have concluded correctly. I am deeply confused.
     
  35. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    In Mono land they call constructed generic types "inflated". That is to say that both
    typeof(List<>)
    and
    typeof(List<int>)
    return generic types, but only the second one is inflated. On the other hand, "Specialization" is not a term I usually see in C# land, but in c++ it's used when a Template is overriden by replacing its generic type parameter with a concrete one.
     
  36. roryo

    roryo

    Joined:
    May 21, 2009
    Posts:
    1,479
    O. M. G.

    I have just started a from-the-ground-up rewrite of Archimatix Pro (a node-based procedural modeling asset for Unity) and discovered SerializeReference! Seems to work flawlessly for graphs.

    Goodbye oh so persnickety GUID-wrangling!
     
    phobos2077 and Stardog like this.
  37. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    :) The report was accepted and I'm genuinely happy for a while. Here's the issue's page: https://issuetracker.unity3d.com/is...s-another-that-has-a-field-with-the-same-name. Also, the issue is marked as fixed because it's not present in 2021.2a; I haven't tested it, but I see no reason for that not to be true. I'm still stuck with 2020 for the foreseeable future, though, so here's hoping it still gets fixed for 2020.3.
     
    Qriva, SonicBloomEric and phobos2077 like this.
  38. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    From my understanding
    Code (CSharp):
    1. [SerializeReference] List<IMyInterface> interfaceList = new List<IMyInterface>()
    should show up in the inspector ("The field type can be an interface" according to the documentation), but for me it doesn't, no list is drawn.
    2020.3.15f2, what could be the issue?

    Edit: even a [SerializeReference] List<object> doesn't show up, which makes me wonder if it works at all.
     
    Last edited: Aug 10, 2021
  39. Qriva

    Qriva

    Joined:
    Jun 30, 2019
    Posts:
    1,314
    From what I remember interfaces are just not supported by inspector and it does not matter if you add SerializeReference attribute. The field can be interface and will be serialized, but inspector will not show up i guess.
     
  40. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    Wow, thanks, that actually seems to be the hint at the solution. I used odin's ShowInInspector attribute to make it visible and it seems to correctly retain the values, so it really just seems to be an inspector limitation.
     
    Qriva likes this.
  41. vertxxyz

    vertxxyz

    Joined:
    Oct 29, 2014
    Posts:
    109
    I have no idea how Odin works, and I have doubts this is compatible with it, but I did make a package a while back that has a drawer for SerializeReference. It should handle interfaces fine iirc.
     
  42. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,091
    Visible in 2021.2:
     
    Flavelius likes this.
  43. chunky_octopus

    chunky_octopus

    Joined:
    Apr 11, 2015
    Posts:
    14
    I am on U21.2.0b10 and I can't see anything.
    When I add
    Code (CSharp):
    1. [SerializeReference] private List<IMyInterface> _myList;
    I can see the list in the inspector, I can add/remove elements but the elements are empty.

    I can't add any value to it.
    Could you please share the code you used?

    Cheers
     
    phobos2077 likes this.
  44. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    There is no built in functionality to assign new instances from inspector provided by unity.
    You can assign them from code.
    Or you can find third-party drawers that allows you to do that from inspector.
     
  45. chunky_octopus

    chunky_octopus

    Joined:
    Apr 11, 2015
    Posts:
    14
    I see... my use-case is actually to have an interface on the inspector where I can drop any Monobehaviour that implements such interface.
     
  46. Catsoft-Studios

    Catsoft-Studios

    Joined:
    Jan 15, 2011
    Posts:
    703
    You don't need to use SerializeReference then. Simply create a class such as:

    Code (CSharp):
    1. public abstract class MyMonoBehaviour : MonoBehaviour
    2. { }
    And then use the following snippet:

    Code (CSharp):
    1. [SerializedField] private List<MyMonoBehaviour> _myList
    This will now only accept classes that extend from your MyMonoBehaviour abstract class
     
    karl_jones likes this.
  47. chunky_octopus

    chunky_octopus

    Joined:
    Apr 11, 2015
    Posts:
    14
    That's not what I want :)
    I want a reference to an interface.

    This solution is closer to what I want, however, I am not happy because I need extra steps to get the interface out of the Object.

    Code (CSharp):
    1.         [SerializeField] [RequireInterface(typeof(ICollisionReceiver))]
    2.         private Object _collisionReceiver;
    3.         private ICollisionReceiver Receiver => _collisionReceiver as ICollisionReceiver;
    I wonder if I could use serialise an Object into the attribute and use it in the PropertyDrawer while having the casted type as a class field, this way:
    Code (CSharp):
    1. [RequireInterface(typeof(ICollisionReceiver))]
    2. private ICollisionReceiver _receiver;
    My first test doesn't serialise the Object in the attribute tho.
     
  48. TextusGames

    TextusGames

    Joined:
    Dec 8, 2016
    Posts:
    429
    Another way is to create some intermediate serializeable class that has private serializable field there you can assign your monobehavior in inspector and public property there monobehavior is casted to specific interface once and cached.
     
    SolidAlloy and oscarAbraham like this.
  49. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    +1. ISerializationCallbackReceiver.OnAfterDeserialize can be used to set the cache to null when the container object is modified in the editor. Caching to reduce casting can be very useful for performance at runtime, specially if the interface is generic, and even more if it is Covariant/Contravariant. That kind of cast is very fast on the editor, but in IL2CPP can be very slow. For example, a particularly complex covariant interface cast can be about as slow as a call to GetComponent, or even slower.

    Another way to avoid the cost of casting is to use UnsafeUtility.As, but you must be completely sure that the cast is valid, or you can introduce some awful bugs. To be honest, I don't think it'd be useful here: I use that trick to save space when needed, replacing a cached cast with a boolean, but it wouldn't even save space in this case.
     
    Last edited: Sep 26, 2021
    Catsoft-Studios likes this.
  50. BayernMaik

    BayernMaik

    Joined:
    Oct 15, 2019
    Posts:
    20
    Any non hacky workarounds, say an official fix on this?
     
    nickicool likes this.