Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

SerializedFields with SerializeReference loses reference to SOME objects of subtypes?

Discussion in 'Scripting' started by Yandalf, May 29, 2020.

  1. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Hello everyone!

    I made a little editor extension that allows me to Serialize inherited types from abstract types and interfaces into a field through the editor. For a while it seemed to function perfectly fine, but today I discovered a case where my objects stored in the field seem to disappear when they're of specific subtypes.
    In pseudo:
    Code (CSharp):
    1. interface IStorable { }
    2.  
    3. [Serializable]
    4. class A : IStorable
    5. {
    6.     public A() { }
    7. }
    8.  
    9. [Serializable]
    10. class B: IStorable
    11. {
    12.     public B() { }
    13. }
    14.  
    15. class Wrapper : MonoBehaviour
    16. {
    17.     [SerializeField][SerializeReference]
    18.     private IStorable storable;
    19. }
    I can then use Wrapper's inspector to set the concrete type of object I want stored in storable (A, B, or whatever other class that implements IStorable), and the editor then creates an object of that type and stores it there using
    Code (CSharp):
    1. SerializedProperty.managedReferenceValue = Activator.CreateInstance(desiredType);
    However, today I noticed that when I stored specific subtypes there the property gets set to null.
    It seems to consistently be the same set of subtypes, but when comparing them to the accepted subtypes I don't see anything in terms of serialization marking or inheritance structure that's different from the types that work without issue.
    Further debugging showed this was not done immediately either, as I logged the stored type within the editor script and it logged the correct type for a few editor updates before an error message gets thrown.
    The message reads

    "Generating diff of this object for undo because the type tree changed.
    This happens if you have used Undo.RecordObject when changing the script property.
    Please use Undo.RegisterCompleteObjectUndo"

    I get this message every time I store a new type of object within the SerializedProperty, and thus didn't really pay it any mind so far as it never caused me trouble, but in the case of the field getting nulled it seems to happen right after this error gets thrown.

    Anyone have a clue on what's going on?

    My editor code that does this whole thing has been posted before, you can find it here.