Stacked Editor Level 1

In Unity there's no option to build a hierarchical view of inspectory so I thought of a simple solution built with two simple scripts providing exactly this feature.

At first you'll need a StackEditor class inheriting from Editor for providing a base-class for every editor which should support hierarchys. It may be built up like this.

using System;
using System.Collections.Generic;
using UnityEditor;
using UObject = UnityEngine.Object;

[Serializable]
public class StackEditor : Editor
{
    private Stack<Editor> activeEditors = new Stack<Editor>();

    public override void OnInspectorGUI()
    {
        if (activeEditors.Count > 0)
            activeEditors.Peek().OnInspectorGUI();
    }

    public void Pop()
    {
        DestroyImmediate(activeEditors.Pop());
    }

    public void Push<T>(UObject target) where T : Editor, new()
    {
        var editor = CreateEditor(target, typeof(T));
        activeEditors.Push(editor);
        if (editor is StackEditorBase)
        {
            var stackEditor = (StackEditorBase)editor;
            stackEditor.StackEditor = this;
            stackEditor.Load();
        }
        Repaint();
    }

    public void Push(UObject target)
    {
        var editor = CreateEditor(target);
        activeEditors.Push(editor);
        if (editor is StackEditorBase)
        {
            var stackEditor = (StackEditorBase)editor;
            stackEditor.StackEditor = this;
            stackEditor.Load();
        }
        Repaint();
    }

    private void OnDisable()
    {
        while (activeEditors.Count > 0)
            Pop();
    }
}

Without further knowledge about the magical StackEditorBase-class it could be rather annoying ... so this class is the base for the simple hierarchical usage of this StackEditor.

using System;
using UnityEditor;

[Serializable]
public class StackEditorBase : Editor
{
    public StackEditor StackEditor
    {
        get; set;
    }

    public virtual string Title => GetType().Name;

    public void Load()
    {
        OnLoad();
    }

    protected virtual void OnLoad()
    {
    }
}

These two scripts should be located in a folder called Plugins\StackEditor\Editor

It could be used like this:

[Serializable]
[CustomEditor(typeof(ContainerObject))]
public class ContainerEditor : StackEditor
{
    public override void OnInspectorGUI()
    {
        EditorGUILayout.LabelField("Container Editor");
        EditorGUILayout.Space();
        base.OnInspectorGUI();
    }

    private void OnEnable()
    {
        Push<ContainerObjectEditor>(target);
    }
}

This is based on how Unity is resolving types internally. The Container-Editor should not contain any logic because the Object-Editor is used for this.

[Serializable]
[CustomEditor(typeof(ConainerObject))]
public class ContainerObjectEditor : StackEditorBase
{
    [MenuItem("Assets/Create/Container")]
    [ContextMenu("Create/Container")]
    public static void CreateObject()
    {
        var path = "";
        var obj = Selection.activeObject;
        if (!obj)
            path = "Assets";
        else
            path = AssetDatabase.GetAssetPath(obj.GetInstanceID());

        if (path.Length > 0)
        {
            if (!AssetDatabase.IsValidFolder(path))
                path = Path.GetDirectoryName(path);
        }

        var instance = CreateInstance<ContainerObject>();
        ProjectWindowUtil.CreateAsset(instance, AssetDatabase.GenerateUniqueAssetPath(path + "/New Container.asset"));
        Selection.activeObject = instance;
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("startTime"));
        serializedObject.ApplyModifiedProperties();
    }
}

For navigating in the hierarchy it's enough to call StackEditor.Push<>() or StackEditor.Pop(). Former goes down the hierarchy, latter navigates a level higher.

StackedEditor Container StackedEditor Level 1 StackedEditor Level 2

If you want to download a sample UnityPackage:

StackedEditor-v0.1.unitypackage

Previous Post Next Post