Stacked Editor

Dieses kleine Plugin erlaubt es dir, schnell und einfach eine Art Hierarchie-Bearbeitung deiner Assets zu bewerkstelligen - in Unity, mit allem, was dir an Unity gefällt.

StackedEditor Intro

Mit der letzten Neuerung kannst du durch alle Ebenen deiner Hierarchie navigieren.

StackedEditor Update

Eine kleine Zusammenfassung

Das erste Skript, ist der sogenannte StackEditor, eine einfache Klasse, die vom Editor erbt und so von allem benutzerdefinierten Inspektoren verwendet werden kann.

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();
    }
}

Nun ist es natürlich langweilig, nicht zu wissen, wie der denn genutzt werden soll ... ganz einfach: Dazu gibt es eine StackEditorBase-Klasse. Diese dient der einfachen Nutzung des StackEditors und seinem hierarchischen Aufbau.

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()
    {
    }
}

Diese zwei Skripte sollten idealerweise in einem Ordner wie Plugins\StackEditor\Editor platziert werden.

Genutzt werden kann dies dann wie folgt:

[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);
    }
}

Hier wird Gebrauch von Unitys Resolve-Verhalten von Typen gemacht, da der Container-Editor nicht alle Logik für das Container-Objekt braucht, was ein eigener Editor wird.

[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();
    }
}

Um dann in der Hierarchie zu wechseln, reicht ein StackEditor.Push<>() bzw. StackEditor.Pop(). Ersteres geht tiefer, letzteres geht eine Ebene höher.

Links

GitHub/AliveDevil/stackededitor Github/AliveDevil/stackededitor/Releases

Neuste Version: StackedEditor-v0.2.unitypackage

Vorheriger Beitrag