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
0
Question by Brad_Schneider · Nov 02, 2018 at 03:11 AM · inspectorserializationserializedpropertyserializedobjectinherited-members

Custom Inspector: Using 'serializedObject' to access inherited members

My desired behaviour is quite simple, yet has been very difficult to achieve. I am no guru at Unity serialization and thus I've been stuck for quite some time on this problem.

To put it plainly, I have a base class that I will call 'BaseClass' and a derived class called 'ChildClass'. BaseClass has many members that ChildClass inherits and uses, with very few of it's own members. None of which I need to see in the inspector. Thus I want to create a custom inspector for BaseClass that all derived classes can use including ChildClass.

Currently my classes are setup as follows:


  [System.Serializable]
  public abstract class BaseClass : Monobehaviour, CustomInterface1, CustomInterface2
  {
      public int m_customInterface1Implementation { get; protected set; }  
      public int m_customInterface2Implementation { get; protected set; }  
  
      public int m_baseClassMember;
  }

 

  [System.Serializable]
  public class ChildClass: BaseClass
  {
  
  }



In my custom inspector I am attempting to access these like this:


  [CustomEditor(typeof(BaseClass), true)]
  public class BaseClassEditor : Editor
  {
      SerializedProperty m_inheritedProperty;
      
      private void OnEnable()
      {
          m_inheritedProperty = serializedObject.FindProperty("m_customInterface1Implementation ")
      }
  
      public override void OnInspectorGUI()
      {
          m_inheritedProperty.objectReferenceValue = (Gameobject)EditorGUILaout.ObjectField("Object", m_inheritedProperty.objectReferenceValue, typeof(GameObject), true);
      }
  }



Now unless I'm simply using the property incorrectly, when I am attempting to use this inspector as is I get a NullReferenceException. This works however with members that are not inherited, so I am led to assume that I cannot access the members inherited from BaseClass from serializedObject directly.

Is it possible to access the inherited members of BaseClass from the serializedObject? I'm new to writing inspectors using serializedObject and SerializedProperties, I've only ever written them using the cast method.


  [CustomEditor(typeof(BaseClass), true)]
  public class BaseClassEditor : Editor
  {
      BaseClass m_baseClassReference;
      
      private void OnEnable()
      {
          m_baseClassReference = (BaseClass)target;
      }
  }



However, it seems it is now preferred to write editors using serializedObject instead of the target cast method. More importantly though, I lose the ability to keep the class members private or protected while still being able to view them through the inspector (for monitoring) since the cast method can only allows regular access to the class you are inspecting.

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

1 Reply

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

Answer by Bunny83 · Nov 19, 2018 at 11:49 PM

Your issue has nothing to do with inheritance but with the simple fact that your two auto properties are not serialized. Unity does not serialize properties at all. Unity only serializes fields as long as they are public or marked with the SerializeField attribute. However the backing field of your auto properties is a private compiler generated field you don't have any access to.


Have a look at the script serialization documentation.


The next issue is that you used "objectReferenceValue" of the serializedProperty but (given that "m_customInterface1Implementation" actually is a field and not a property) it's actually of type int. For an int type you have to use SerializedProperty.intValue. Likewise "EditorGUILaout.ObjectField" only works for actual reference types that are derived from "UnityEngine.Object" (like Transform / Component, GameObject, Mesh, ...).


There's no issue using properties in your class, but if you want them to be serializable you need to use an explicitly declared backing field which you serialize. Keep in mind that Unity doesn't care about your properties at all. Unity only cares about your serializable fields

 public abstract class BaseClass : Monobehaviour, CustomInterface1, CustomInterface2
 {
     [SerializeField]
     private int m_BackingField1;
     public int m_customInterface1Implementation { get{ return m_BackingField1;} protected set {m_BackingField1 = value;} }
     
     [SerializeField]
     private int m_BackingField2;
     public int m_customInterface2Implementation { get{ return m_BackingField2;} protected set {m_BackingField2 = value;} }
     
     public int m_baseClassMember;
 }
  
 public class ChildClass: BaseClass
 {
 }

Those classes have proper field that are serialized. Note that a custom editor can not change what fields are serialized or not. A custom editor just provides a custom way to present the serialized data to the user. Note when you want to create a custom editor for your class you can only read / write the backing fields, not the properties.


You might have confused Untiy's "SerializedProperty" with an actual "C# property". They have nothing in common and belong to completely different things.

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 Brad_Schneider · Dec 22, 2018 at 12:22 AM 0
Share

I really appreciate the detailed answer, my apologies for responding a month late. Seems I disabled email notifications and never realized I received an answer!

I actually haven't had the time to come back to this problem yet, but when I do I think I have a better idea of where to start up again, thanks!

Seems however, I won't be able to get my desired functionality which is to access private variables through the inspector in a way that ignores access modifiers (as if everything is public). I'll have to come up with a different approach I suppose. Thanks again!

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

101 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

Related Questions

Error when trying to Serialize a field that is in a class 0 Answers

Replicate "Apply" and "Revert" button functionality in ScriptableObject Editor Inspector 2 Answers

Why are the children of my Serialized Property not being drawn? 1 Answer

Finding property with serializedObject on script with a generic 0 Answers

Where can I find the default "serialized data" files that Unity save and load during run-time / editor time from the inspector? 0 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