Search Unity

Question Custom Inspector for base class, still show child class's default inspector

Discussion in 'UI Toolkit' started by RGVexed, Feb 4, 2023.

  1. RGVexed

    RGVexed

    Joined:
    Jul 14, 2015
    Posts:
    8
    Is it possible to create a base class with a custom inspector and when inherited show both the base class's inspector as well as the child's?

    for example I have this base class:
    Code (CSharp):
    1.     [CustomEditor( typeof( ClientBehavior ) ,true) ]
    2.     public class ClientBehaviorInspector : Editor
    3.     {
    4.         public override VisualElement CreateInspectorGUI()
    5.         {
    6.             VisualElement i = new VisualElement();
    7.             i.Add(new Label("This is a custom inspector"));
    8.             return i;
    9.         }
    10.     }
    and this child class that inherits from ClientBehavior:
    Code (CSharp):
    1. public class NetworkPlayer : ClientBehavior
    2. {
    3.     public int test;
    4. }
    Is it possible to show the custom inspector as well as display the child's public 'test' field in the inspector without having a custom editor for the NetworkPlayer class?
    so that it looks like:
    Code (csharp):
    1. This is a custom inspector
    2. test    [0]
     
  2. wechat_os_Qy01TK4pL1FdWViLhLHfZNl3E

    wechat_os_Qy01TK4pL1FdWViLhLHfZNl3E

    Joined:
    Sep 26, 2022
    Posts:
    9
    You can use reflection:
    Code (CSharp):
    1. using System.Reflection;
    2. using Unity.VisualScripting.FullSerializer.Internal;
    3. using UnityEditor;
    4.  
    5. [CustomEditor(typeof(ClientBehavior), true)]
    6. public class CustomClientBehavior : Editor
    7. {
    8.     public override void OnInspectorGUI()
    9.     {
    10.         EditorGUILayout.LabelField("This is a custom inspector");
    11.     }
    12. }
    13.  
    14. [CustomEditor(typeof(NetworkPlayer), true)]
    15. public class CustomNetworkPlayer : CustomClientBehavior
    16. {
    17.     public override void OnInspectorGUI()
    18.     {
    19.         base.OnInspectorGUI();
    20.         MemberInfo[] infos = typeof(NetworkPlayer).GetDeclaredMembers();
    21.         foreach (var info in infos)
    22.         {
    23.             SerializedProperty property = serializedObject.FindProperty(info.Name);
    24.             if(property == null)
    25.                 continue;
    26.             EditorGUILayout.PropertyField(property);
    27.         }
    28.     }
    29. }
    or
    Code (CSharp):
    1. using System.Reflection;
    2. using Unity.VisualScripting.FullSerializer.Internal;
    3. using UnityEditor;
    4.  
    5. [CustomEditor(typeof(ClientBehavior), true)]
    6. public class CustomClientBehavior : Editor
    7. {
    8.     public override void OnInspectorGUI()
    9.     {
    10.         EditorGUILayout.LabelField("This is a custom inspector");
    11.         MemberInfo[] infos = target.GetType().GetDeclaredMembers();
    12.         foreach (var info in infos)
    13.         {
    14.             SerializedProperty property = serializedObject.FindProperty(info.Name);
    15.             if(property == null)
    16.                 continue;
    17.             EditorGUILayout.PropertyField(property);
    18.         }
    19.     }
    20. }
     
  3. RGVexed

    RGVexed

    Joined:
    Jul 14, 2015
    Posts:
    8
    Thanks, using reflection is a good idea. I did however end up going with the following to get the default inspector appended to my base class's ui toolkit inspector.

    Code (CSharp):
    1. public override VisualElement CreateInspectorGUI()
    2. {
    3.     VisualElement root = new VisualElement();
    4.     IMGUIContainer defaultInspector = new IMGUIContainer(() => DrawDefaultInspector());
    5.     root.Add(defaultInspector);
    6. }