Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 Joshua P. R. Pan · Jan 11, 2015 at 06:09 PM · editorinheritancecustom editorcustom-inspector

Can a class's Editor call its component's Editor? Likewise, can a derived class's Editor call its base class's Editor?

Dear all, I'm trying to customize Unity Editor, and the following problem keep bothering me. To make it brief: Can the OnInspectorGUI() of Customized Editor behaves like a Constructor that can call its components' OnInspectorGUI() ? How? Likewise for the derived class, how can I call its base class's OnInspectorGUI()?

For Component Case:

Suppose I'm writing class Player, and it has a Component: CharacterAttribute. And now I'm writing the Customized Editor for Player, can I call the Editor of CharacterAttribute?

 // In "Player.cs":
 public class Player : MonoBehaviour
 {
     CharacterAttribute attribute;
     [SerializeField] Armer armer;
 }
 
 // In "CharacterAttribute.cs", it has Customized Editor already defined in "CharacterAttributeEditor.cs"
 public class CharacterAttribute  : MonoBehaviour
 {
     float healthPoins;
 }
 
 // In "PlayerEditor.cs":
 [CustomEditor( typeof(Player), true )]
 public class PlayerEditor: Editor
 {
     public override void OnInspectorGUI()
     {
         base.OnInspectorGUI (); // this seems only display "armer" in the Inspector, but no CharacterAttribute
     }
 }

For Inheritance Case:

For inheritance case, suppose I have a abstract class Human, it define some basic Live attribute. Then I define a custom Editor for abstract class Human.

Latter, I define a class Warrior that inherit from Human, and has extra data members such as Attack attribute (thus a Editor with extra column should be added.). However, the base.OnInspectorGUI() of Warrior seems will not call the Editor of Human at all...

I have tried to use another approach by eliminate the HumanEditor. Instead, in class Human I define a drawInspector() that contained the original content in HumanEditor.OnInspectorGUI(). And will be called by WarriorEditor.OnInspectorGUI(). This approach can fulfill what I want in the Inspector but kind of silly. Moreover, I can't use the Unity default inspector of class Warrior by base.OnInspectorGUI(). Otherwise, not only the Warrior will be Draw, but also the Human...

 // Human.cs
 [System.Serializable]
 public abstract class Human : MonoBehaviour  // its Editor has been customized
 {
     [SerializeField] private float health;
     
     public void drawInspector() //define a Editor callback
     {
         // Draw the Basic Inspector for Human

         EditorUtility.SetDirty (this);
     }
 }
     
 // Warrior.cs
 public class Warrior : Human
 {
     float attack;
 }
     
 // WarriorEditor.cs
 [CustomEditor( typeof(Warrior) )]
 public class WarriorEditor : Editor
 {
      public override void OnInspectorGUI()
      {
          Warrior warrior = this.target as warrior;
          warrior.drawInspector(); //display the Inspector of Human
      }
 }

Any idea? Thanks.

PS. I'm using Unity 4.6.1

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
1
Best Answer

Answer by GameVortex · Jan 11, 2015 at 07:24 PM

You are using the term class and component a little weird so it was kind of hard to follow this question at the beginning. In Unity a Component is a class which inherits from MonoBehaviour and they cannot have other components, but they can have references to them in a variable/property.

Anyway, yes what you are describing is perfectly possible.

Component case:

The most elegant solution here would be to create a PropertyDrawer for the CharacterAttribute. This will make it easy to have the EditorGUI for CharacterAttribute be drawn wherever CharacterAttribute is used, except it cannot be used for a MonoBehaviour (which CharacterAttribute is).

Another way would be to create a normal CustomEditor Inspector for it and have all its GUI functionality done in a public static function which both the custom inspector for characterattribute and player uses.

Example:

 [CustomEditor(typeof(CharacterAttribute))]
 public class CharacterAttributeInspector : Editor
 {
     private CharacterAttribute attribute;
     private void Awake()
     {
         attribute = (CharacterAttribute)target;
     }
 
     public override void OnInspectorGUI()
     {
         OnCustomInspectorGUI(attribute);
     }
 
     public static void OnCustomInspectorGUI(CharacterAttribute characterAttribute)
     {
         //Do gui stuff here
     }
 }

Then also call the static function from the Player inspector when needed.

Example:

 [CustomEditor(typeof(Player))]
 public class PlayerInspector : Editor
 {
     private Player player;
     protected virtual void Awake()
     {
         player = (Player)target;
     }
 
     public override void OnInspectorGUI()
     {
         //Draw the characterAttribute gui:
         CharacterAttributeInspector.OnCustomInspectorGUI(player.characterAttribute);
 
         //Do other player GUI stuff...
     }
 }
 

Inheritance case:

You cannot do Editor functionality inside of MonoBehaviours, so the drawInspector thing will not work (it may seem like you can if you include using UnityEditor in the class, but then you will get a lot of problems when building the project).

What you want can be achieved by having the custom Inspector for the warrior class inherit from the inspector for the human class. So the warrior inspector will call base.OnInspectorGUI() which will be the human inspectors OnInspectorGUI().

Here are some example scripts:

 public class Human : MonoBehaviour 
 {
     public float health;
 }

 public class Warrior : Human 
 {
     public float attack;
 }

 [CustomEditor(typeof(Human))]
 public class HumanInspector : Editor
 {
     private Human human;
     protected virtual void Awake()
     {
         human = (Human)target;
     }
 
     public override void OnInspectorGUI()
     {
         EditorGUILayout.BeginVertical(GUI.skin.box);
         EditorGUILayout.LabelField("Human Settings");
         human.health = EditorGUILayout.Slider("Health", human.health, 0, 100);
         EditorGUILayout.EndVertical();
     }
 }

 [CustomEditor(typeof(Warrior))]
 public class WarriorInspector : HumanInspector 
 {
     private Warrior warrior;
     protected virtual void Awake()
     {
         base.Awake();
 
         warrior = (Warrior)target;
     }
 
     public override void OnInspectorGUI()
     {
         base.OnInspectorGUI();
 
         EditorGUILayout.Space();
 
         EditorGUILayout.BeginVertical(GUI.skin.box);
         EditorGUILayout.LabelField("Warrior Settings");
         warrior.attack = EditorGUILayout.Slider("Attack Power", warrior.attack, 0, 100);
         EditorGUILayout.EndVertical();
     }
 }


If you attach a Human to a GameObject you will see it only draws the Health slider, and when you attach a Warrior to a GameObject you see it draws both the Health slider and the Attack Power slider. Note that the Human Inspector has the awake function set as protected (so the warrior inspector can get it) and virtual (so the warrior inspector can override it), because only the Warrior Inspector will have its functions called by Unity so the Warrior Inspector will have to call the Human Inspectors functions.

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 Joshua P. R. Pan · Jan 12, 2015 at 02:33 AM 0
Share

Thanks, this is what I want! Also, I appreciate your patient to understand my question.

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

C# unity custom editor multiple different components but same base class 2 Answers

Editable non-monobehaviour objects 1 Answer

Generic CustomEditor 0 Answers

Custom editor does not work well after Play 1 Answer

Questions Regarding Images in Custom Inspector/Editor 1 Answer


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