WonderlandManagerEditor
Motivation
The ManagerEditor provides a system to make an editor for a "Main Component and its managed components".
Managed MonoBehaviours are automatically hidden in inspector.
Example
Create the editor
Editor for MyManager behaviour.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using EODE.Wonderland;
[CustomEditor(typeof(MyManager))]
public class MyManagerEditor : WonderlandManagerEditor {
}
Basic configs
[CustomEditor(typeof(MyManager))]
public class MyManagerEditor : WonderlandManagerEditor {
// List the managed MonoBehaviour types
protected override System.Type[] ManagedTypes {
get {
return new System.Type[] { typeof(IMyManagedInterface), typeof(MyManagedBehaviour) };
}
}
// Titles for each types in inspector
protected override string[] TitlesInInspector {
get {
return new string[] { "Children A", "Children B" };
}
}
// change the content background
// default = null, use Wonderland bg.
// for example create a file : Editor/Resources/MyManager.png
// a banner aspect is recommanded (for example, default bg size is 256*74)
protected override string BackgroundImage => "MyManager";
...
}
Managed editor config
List and configure managed behaviours.
public class MyManagerEditor : WonderlandManagerEditor {
...
// select the managed editor class
protected override ManagedBehaviourEditor CreateManagedBehaviourEditor(System.Type managedType) {
if (managedType == typeof(IMyManagedInterface)) {
return new IMyManagedInterfaceEditor();
}
return new MyManagedBehaviourEditor();
}
// default true, draw a [+] button for a managed type
protected override bool CreateAddButton(System.Type managedType) {
if (managedType == typeof(IMyManagedInterface)) {
return false;
}
return true;
}
class IMyManagedInterfaceEditor : ManagedBehaviourEditor {
protected override void Draw() {
DrawDefaultContent();
}
}
class MyManagedBehaviourEditor : ManagedBehaviourEditor {
protected override void Draw() {
DrawDefaultContent();
}
}
...
}
Managed editor
Override managed behaviours editor.
class IMyManagedInterfaceEditor : ManagedBehaviourEditor {
// disable the remove button on right clic
protected override bool CreateRemoveButton() {
return false;
}
// menu content
protected override void UpdateMenu() {
_menu.AddItem(new GUIContent("Test"), false, () => {
Debug.Log("test");
});
}
// update component data, optimize render
protected override void Update() {
}
// component content
protected override void Draw() {
// Init editor if necessary + draw all but a list
DrawContentExcluding(new string[] { "m_Script", "_value" });
// Init editor if necessary + draw a field list
DrawContentIncluding(new string[] { "_value" });
// manually (you must call DrawContentXXX before to initialize the editor !)
EditorGUILayout.PropertyField(_editor.serializedObject.FindProperty("MyValue"));
_editor.serializedObject.ApplyModifiedProperties(); // auto call in DrawContentXXX, but necessary here to save your custom fields
}
public override bool RequiresConstantRepaint() {
// default false, force repaint at all frames
return Application.isPlaying; // example : update always is application running
}
...
}
Managed MonoBehaviour
A managed MonoBehaviour inherits an IManagedComponent
interface.
public class MyManagedBehaviour : MonoBehaviour, IManagedComponent {
public virtual string EditorTitle => GetType().Name;
public virtual Texture2D EditorIcon => null; // icon gen by code
public virtual string IconPath => "MyManagedIcon";
...
}
A managed MonoBehaviour can inherit an IIndexabled
interface.
public class MyManagedBehaviour : MonoBehaviour, IManagedComponent, IIndexabled {
[SerializeField][HideInInspector] protected int _index = 0;
public virtual int Index {
get { return _index; }
set { _index = value; }
}
...
}
The managed MonoBehaviour become reorderable.
HideFlags
It is highly recommended to add an OnValidate
method to make the component visible when its manager is destroyed.
void OnValidate() {
if (GetComponent<MyManager>() == null) {
hideFlags = HideFlags.None;
}
}
DrawGuizmos
By default, OnDrawGuizmos is not called in managed behaviours (because inspectors are hidden). Add 2 methods in your manager editor to active it.
[DrawGizmo(GizmoType.Selected | GizmoType.NonSelected)]
static void OnDrawGizmos(GameEntity ge, GizmoType gizmoType) {
foreach (var aspect in ge.GetComponents<GameEntityAspect>()) {
var meth = aspect.GetType().GetMethod("OnDrawGizmos", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy);
if (meth != null) {
meth.Invoke(aspect, null);
}
}
}
[DrawGizmo(GizmoType.Selected)]
static void OnDrawGizmosSelected(GameEntity ge, GizmoType gizmoType) {
foreach (var aspect in ge.GetComponents<GameEntityAspect>()) {
var meth = aspect.GetType().GetMethod("OnDrawGizmosSelected", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.FlattenHierarchy);
if (meth != null) {
meth.Invoke(aspect, null);
}
}
}