Search Unity

Change ReorderableList element's type within the inspector.

Discussion in 'Scripting' started by Ziplock9000, Jun 25, 2019.

  1. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    I have a scriptable object that contains some variables along with a "List<QuestStepRoot> QuestDataSteps=new List<QuestStepRoot>" which I have a Reorderable list in an inspector to allow me to add/remove and edit each element in it. Each element also has its own variables like name, description that I can edit. Nothing special here and it works.

    However, I now have different types of QuestStepRoot now, with different functionality. So I've introduced inheritance to make QuestStepValue and QuestStepItem inherit from QuestStepRoot.

    This now breaks the inspector, specifically the Reorderable list. There's two things I need to fix in order for it to work:
    1) I need to be able to dynamically change the type of the element from QuestStepValue and QuestStepItem based on a dropdown (that I already have working). .I just don't know how to actually cast.

    2) I need to be able to check the type to display the step properly in the field.

    Now I have access to the element:
    SerializedProperty element = QuestSteps.GetArrayElementAtIndex(index);

    But I don't see a way to access the actual element (QuestStepValue or QuestStepItem) without using one of the casting functions, ie intValue. Which obviously would not work.
    I need to be able able to access the raw element as a QuestStepValue and QuestStepItem to be able to test the type and flip it's type with a new when needed.

    I think they key is when pressing the plus to add a new item, it needs to somehow ask me which one of the two subtypes I want to add. I've no idea if this is even possible.
    So I need to be able to override "displayAdd" somehow. Also I need access to the actual element so I can test it's type.


    Prior to this QuestStepRoot has the functionality of both QuestStepValue and QuestStepItem which is messy considering some of the fields are not even used when it's a certain "mode".
     
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    Basically you can't since Unity do not support serialization of arrays containing different types of objects.
     
    Ziplock9000 likes this.
  3. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    Ok well that got straight to the answer. Thanks.
     
  4. Ziplock9000

    Ziplock9000

    Joined:
    Jan 26, 2016
    Posts:
    360
    However I noticed this conveniently the other day:
    https://forum.unity.com/threads/serializereference-attribute.678868/

    "The field attribute is for serializing reference types (c# class, not structs) by reference as opposed to by value (as is the default behaviour).

    This allows:
    - Expressing graphs without having to resort to ScritableObjects for each node in the graph.
    - Polymorphic data, ex: List<IFoo>;"

    This should it now possible?

    But it still remains on *how* I do this, which means as far as I can tell I need access to the underlying type of the element, be it "QuestStepValue" or "QuestStepItem"

     
  5. bszalapski

    bszalapski

    Joined:
    Feb 21, 2020
    Posts:
    4
    Did you find a way to do this?
     
  6. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    There's a way to do this. Use scriptable objects. Make your base class inherit from Scriptable Objects, that allows the Unity editor to take in ANY subclass and use it in the inspector.

    But
    as you might notice, you can't directly edit it. That's because Unity doesn't support serialization of scriptable objects by default. So, what are you going to do? - You're going to write a custom property drawer that draws scriptable objects in any inspector field. That's going to take ages. I had a similar problem a few months back and I went through the entire hassle. It's not pretty. Try looking for "ExpandableAttributeDrawer" git repo somewhere online. Someone already solved this and you basically need only 2 scripts to make it work.

    Once that works, you'll be able to see and edit all subclasses in the inspector with no issues. It's a ton of work and it's ridiculous that such a feature is not built in already. Good luck.

    Edit:
    You're in luck. I've managed to dig up my post that had a similar topic:
    https://forum.unity.com/threads/array-of-arrays-in-inspector.857563/#post-5653291
    https://gist.github.com/RedDude
     
    Last edited: Sep 25, 2020