Draw Inspector within another Inspector

Hey everyone,

so while trying to draw an inspector within another inspector I almost decided to jump out of the window, but instead decided to post a thread. Maybe some Unity Dev or UI Guru can help me out. I’m on 2019.1.14f1.

The TL;DR is: using InspectorElement doesn’t create PropertyFields, but instead they are empty. See this image:

The detailed version: I created a few simple scripts to test how to do it. The premise is simple: Draw the members from TestComponent2 in the Inspector of TestComponent1.

public class TestComponent1 : MonoBehaviour
{
    public int TestValue1 = 15;
    public TestComponent2 RefToComponent;
}
public class TestComponent2 : MonoBehaviour
{
    public int TestValue2 = 55;   
}

I have then created a simple CustomEditor for TestComponent2:

[CustomEditor(typeof(TestComponent2))]
public class TestComponent2Editor : Editor
{
    public override VisualElement CreateInspectorGUI()
    {
        VisualElement root = new VisualElement();
        root.Add(new PropertyField(serializedObject.FindProperty("TestValue2")));
        return root;
    }
}

So far so good because eerything works as intended. Now to the apparently tricky stuff: I want to display the above inspector in the inspector of TestComponent1.

[CustomEditor(typeof(TestComponent1))]
public class TestComponent1Editor : Editor
{
    public override VisualElement CreateInspectorGUI()
    {
        VisualElement root = new VisualElement();
        var prop = serializedObject.FindProperty("RefToComponent");
        root.Add(new PropertyField(serializedObject.FindProperty("TestValue1")));
        root.Add(new PropertyField(prop));
        if (prop.objectReferenceValue != null)
            root.Add(new InspectorElement(prop.objectReferenceValue));
        return root;
    }
}

The important bit is this line:
root.Add(new InspectorElement(prop.objectReferenceValue));
This innocent line actually doesn’t really do anything. It creates the necessary elements but the PropertyField’s are empty. There is nothing attached to it. How do I work around this issue?

What I did was I got the Editor for the object with editor = Editor.CreateEditor(object), then I check if it’s a UIElements Inspector:
var root = editor.CreateInspectorGUI() then you have to check if the root is null. If the root is null, that means that it doesn’t use UI Elements, so you can create a new IMGUIContainer, and in onGUIHandler callback, call editor.OnInspectorGUI().

You might need to fiddle around with it to get it to work with what you’re working with, but that should give you a good starting point. Oh, and if it is a UI Elements inspector, then you’ll of course want to add the “root” to your container element.

2 Likes

Thank you for taking the time to respond. I’ve played around with it a bit but to no avail. Still comming up with empty property fields. Can you provide your working example for me to analyse?

Oh, I see what your problem is. Your classes aren’t serializable. You should be using the attribute System.Serializable.

Aside from that, I believe that you should be using ScriptableObjects. If I remember correctly, it is inadvisable to just use a regular class.

MonoBehaviours don’t need the attribute System.Serializable because they are seriaizable by default. I don’t use regular classes anywhere.

Oh, my mistake. Could you share a screenshot of what your inspector looks like?

It looks like your issue may be related to this bug I’ve just encountered here Adding property field to root after CreateInspectorGUI

Although I’m doing something pretty different in my case I get a hierarchy that looks similar to yours with those empty Property Fields so I’m betting the underlying issue is the same or similar.