Troubles with polymorphic list

Issue #232 resolved
Former user created an issue

I just purchased Odin Inspector at 50% off (yay!) and installed it in a test project of mine. Odin: v1.0.5.3 Unity: 2017.1.2p2 OS: Windows 7, 64 bit

I've got a class, Chain:

public abstract class Chain : ScriptableObject { public string name; }

And a subclass Type1LegChain:

public class Type1LegChain : Chain {}

And this in a component:

[SerializeField]
[HideReferenceObjectPicker]
[InlineEditor]
[ListDrawerSettings(ListElementLabelName = "name")]
private List<Chain> chains = new List<Chain>();

Here's what it looks like in the inspector:

Capture1

Based on the attributes I'm using, I would expect the object picker to be hidden and the "name" property of the Type1LegChain instance to be displayed (it is definitely set to a non-null value). Neither of those is happening. Am I doing something wrong?

Additionally, when I click the "+" icon to add an element to the list, I get a normal Unity picker dialog titled "Select Chain", but it doesn't list anything. I would have hoped it listed the Type1LegChain class (and eventually other classes that inherit from Chain. Are my expectations too high? If so, how would I go about making that happen?

Comments (7)

  1. Tab Bennedum

    I'm the OP. I had to create an account so I could comment and properly add the image that didn't link correctly:

    Capture1.png

  2. Tab Bennedum

    Ideally, I'd like to have each list element displayed as text with the list element's name property value, followed by the list element's class name. I don't want to be able to change the element's type after it's added. I still want inline editing, but having the pencil icon to pop open a dialog for editing is OK. It would also be nice to not allow a context menu to set the element to null.

    And of course, I'd love to have the "+" icon pop up a dialog where I can select any of the subclasses of "Chain".

  3. Tor Esa Vestergaard

    Alright, the name issue was a bug, and I have fixed that bug now. The object reference picker isn't hidden, because it's not shown at all to begin with. The object reference picker never shows for Unity objects - they have their own selection system. InlineEditor always renders a header that designates the object that it is an inline editor for. You can configure the attribute to start with the header expanded by default, if you'd like, but right now there is no way to get rid of it.

    The name issue was because of a bug in the code that Odin was using to find the member to get the value of - namely, we were finding the UnityEngine.Object.name property, rather than your name field. Now we will always find the "lowest" possible compatible member. For now, you can resolve the issue by not naming your field "name", which conflicts with Unity's own name property - you should already be getting warnings about that being a bad idea.

  4. Tab Bennedum

    I understand the bug aspect. I've always used the "name" property with the "new" keyword (which my example didn't have) because Unity does nice things with it automatically (when not using Odin to draw the properties). Granted, I could just leave out my "name" property since it already exists in the underlying class.

    I think I understand what your saying about the InlineEditor stuff, but I guess I don't understand what the "Object Reference Picker" is. In the example I provided, I can click the little "circle" think to the right of the class name and a picker dialog pops up. I don't want that. Also, I click the object name and press the delete key and the array/list entry is set to null, which I also don't want. Is there a way to prevent those things from happening?

    I should also mention, in my example, the "Chain" class inherits from ScriptableObject. I have to real need to inherit from that class at all. Ideally, Chain should inherit from System.Object. But when I do that, Odin doesn't draw anything for the array property. Maybe that's a separate issue.

  5. Tor Esa Vestergaard

    The Object Reference Picker is what you get when Odin is serializing your System.Object-derived polymorphic types. You cannot hide the "object picker" aspect of the InlineEditor, because it's a Unity object specific thing, not the generic object picker. Right now those are two different things.

    As for Odin not drawing anything if you don't derive Chain from ScriptableObject, that would be because whatever object you have the List<Chain> in isn't being serialized by Odin. Please see this faq question and this manual page for more info.

  6. Tab Bennedum

    Having my Component inheriting from SerializedMonoBehaviour solved all my problems. I've been able to remove the dependency on ScriptableObject and I now have my polymorphic arrays/lists working exactly as I wanted them! I can even select from a list of concrete classes when using the built-in "add" button. Thanks!

  7. Log in to comment