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.
Mit der letzten Neuerung kannst du durch alle Ebenen deiner Hierarchie navigieren.
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 StackEditor
s 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.
GitHub/AliveDevil/stackededitor Github/AliveDevil/stackededitor/Releases