Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by ParkourTeddy · Oct 04, 2019 at 06:47 PM · listpropertydrawertypessubclassing

PropertyDrawer for list. Subclass item fields not showing. Help needed!

Confusing title, I know... Here's what I mean: I'm trying to draw a list of objects of the class Action. Every element in the list is a different type of subclass of Action (for example Idle, Leap or Wait). The problem is that I want to modify the specific values of these subclasses but their fields are currently not showing up when I use the Editor.propertyField(property: action, includeChildren: true). alt text

This is what I want: alt text I think the reason for this problem is I'm using a List<Action> for storing my subclasses. Thus the property automatically assumes all objects are of class Action (which only has one public variable "privateName") and not the subclasses Wait, Idle or Leap. Is there any way to draw all of the fields of the subclass when having them in a list? I'm currently using a Reorderable list to draw my actions and am currently calling Editor.propertyField(property: action, includeChildren: true) on each and every one to display them. This is the code i use to create my list. public List<Action> actionList = new List<Action>();

unity-2019-10-04-20-22-03.png (2.6 kB)
unity-2019-10-04-19-55-18.png (6.5 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Oct 05, 2019 at 01:06 AM

Custom serializable classes do not support inheritance and polymorphism when it comes to serialization. Such classes are always serialized based on the field type. No type information is stored in the serialized data.


Please read this page carefully


CustomEditors or Property drawers can only change how the data is presented. You can not change the way how it's serialized.


There are ways to implement custom serialization logic by implementing the ISerializationCallbackReceiver interface. However it's only meant to convert things that can not be serialized into data that can be serialized.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ParkourTeddy · Oct 06, 2019 at 03:44 PM 0
Share

I'm not very used to using unity answers so I had to make my comment into an "answer". I have clarified my question inside that answer, so please check it out. :)

avatar image
0

Answer by ParkourTeddy · Oct 05, 2019 at 06:53 PM

@Bunny83 Thanks for your answer. Though it doesn't quite answer my question, but I don't think I made myself clear enough, so I'll try again. I will try to show you the behavior I want and what I am currently getting from a simple example.

TLDR can be found at the bottom.

Let's say we have a script QAction (The Q doesn't stand for anything, it's just there to not interfere with my other scripts).

 [System.Serializable]
 public class QAction
 {
         [HideInInspector]
         public string actionName = "Empty Action";
         public string privateName = "";
 
         public virtual void Act()
         {
             Debug.Log("(" + actionName + ") Somebody called me!");
         }
 }

Then we have two subclasses of QAction. QWalk and QJump.

 [System.Serializable]
 public class QWalk : QAction
 {
     public float speed = 10f;
     public float duration = 15f;
 
     public QWalk()
     {
         actionName = "Walk";
     }
 
     public override void Act()
     {
         Debug.Log("(" + actionName + ") is walking!");
     }
 }

 [System.Serializable]
 public class QJump : QAction
 {
     public float jumpHeight = 5f;
     public float airTime = 2f;
 
     public QJump()
     {
         actionName = "Jump";
     }

     public override void Act()
     {
         Debug.Log("(" + actionName + ") Jumped!");
     }
 }



Now let's say I want a property drawer for QWalk (To keep this simple I'll just add some extra space below the property).

 [CustomPropertyDrawer(typeof(QWalk))]
 public class QWalkDrawer : PropertyDrawer
 {
     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
     {
         EditorGUI.PropertyField(position, property, includeChildren: true);
     }
 
     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
     {
         return EditorGUIUtility.singleLineHeight * 7f;
     }
 }

Everything works as intended, I can see my property and there is some extra space below it (see picture below). Now let's say I want to make a nice propertydrawer for a list of actions, so I create a script for the QActionList and a QActionListDrawer.

 [System.Serializable]
 public class QActionList
 {
     public QAction[] actionList = new QAction[3] { new QWalk(), new QJump(), new QAction() };
 }

 [CustomPropertyDrawer(typeof(QActionList))]
 public class QActionListDrawer : PropertyDrawer
 {
     SerializedProperty list;
     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
     {
         list = property.FindPropertyRelative("actionList");
         EditorGUI.PropertyField(position, list, includeChildren: true);
     }
 
     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
     {
         return EditorGUIUtility.singleLineHeight * 10f;
     }
 }
 

Let's also create a simple container where we can view how the different drawers look.

 public class QTestContainer : MonoBehaviour
 {
     public QJump jumpAction;
     public QWalk walkAction;
     public QActionList actionList;
 }

But when I view the script in the inspector I get the following... alt text

We can see that the two first elements (Jump Action and Walk Action) are being drawn correctly, but in the list both the Jump and Walk actions are missing fields. Thus I cannot access the values of Walk and Jump because (I suspect) the array only draws the fields inherited from QAction. How can I fix this (or work around it) so that I easily can edit the different actions when inside an array or list?

TLDR: For some reason when drawing the actions using a list, Unity only draws the fields of the base class QAction instead of drawing them as in the picture above "Jump Action" and "Walk Action" which is the way I want them to be displayed inside of the array "Action List".


unity-2019-10-05-20-38-50.png (34.6 kB)
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Glurth · Oct 06, 2019 at 05:25 PM 1
Share

UA stuff: I've upvoted your question, hopefully that should give you enough karama to add comments. I don't think this this answer you've created CAN be properly converted to a comment (so I won't do it). But in the future, I'd suggest you edit/add to your Question, rather than create an "answer" with more question details.

What Bunny was talking about was this class's member, the array definition:

  [System.Serializable]
  public class QActionList
  {
      public QAction[] actionList = new QAction[3] { new QWalk(), new QJump(), new QAction() };
  }

Even though you instantiated all those elements as QWalk or QJump, they will only be SERIALIZED as QActions. $$anonymous$$eaning, only the fields in the QAction class will be serialized. Therefore you will NOT have the data specific to QWalk available in your SerializedProperty when drawn.

To be serialized properly, you must declare, in your QActionList class, an array of EACH type to be serialized (like your counter-example). THEN, you can use the ISerialization callbacks, to convert/merge this into a single (not-serializable) list of QActions for runtime use (and back to multiple lists for serialization). The QActionList property drawer will , I suspect, need custom code to "fake" the multiple arrays into looking like a single list.

avatar image ParkourTeddy Glurth · Oct 13, 2019 at 06:29 PM 0
Share

Thank you! This clarified everything a lot! :)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

117 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

A node in a childnode? 1 Answer

CustomPropertyDrawer of a Generic List. 1 Answer

DropDownList with string array in Property Drawer 0 Answers

[RESOLVED] List get empty after certain time. 1 Answer

Null reference exception: Object reference not set to an instance of an object 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges