If you ever tried extending Unity’s editor in order to create your own custom panels, you already know how it feels. If you never did that, let me explain it simply and with a zombie allegory (since it seems that everything needs to contain undead guys in these days): it’s like being a zombie superhero (or supercriminal). You know you have immense power at your fingertips, but your fingertips keep falling off. Allegories apart: the UnityEditor classes allow you to build the stuff of your dreams, while the lack of documentation will make you cry in despair.
I developed a lot of Unity Editor panels. But each time I get back to creating a new one (as in the last week), I tend to forget something, and then have to fight tons of error messages and un-working chinks of code. So here is my workflow, and a couple things to keep in mind when doing this kind of stuff.
My workflow
I hate the way Unity manages classes, and especially the lack of namespaces. No one could state it’s nothing less than incredibly messy and annoying. To avoid going crazy, since a while I do all my code as one or more external C# assemblies, editor-related or not. There are many advantages, like:
- code-completion works as it should
- no more conflicts between non-public classes with the same name but in different namespaces (sadly, I still have to use a prefix for all public classes instead, in order to avoid conflicts with eventual non-assembly ones in Unity assets)
- you can use all access modifiers! being able to label stuff as protected or internal is not simply awesome: it’s needed
- and many more
Being on Windows, to link my DLLs to a Unity project I simply use symbolic links (I used to create them via console, but since some month I discovered symlinker and stick to it). Also, I use a post-build process to convert debug PDB files to MDB (using pdb2mdb, which is also included with Unity), otherwise Unity isn’t able to log the correct row in case of errors.
Ok, on to those couple tips.
Things to keep in mind
Inheritance
Sadly, Unity objects (meaning UnityEngine.Object derived classes) don’t support generic inheritance. This means that, for example, this is ok:
1 2 | public MySuperWindow : EditorWindow {} public MySubWindow : MySuperWindow {} |
While this is not:
1 2 | public MySuperWindow<T> : EditorWindow {} public MySubWindow : MySuperWindow<Something> {} |
Undo
Undo is another messy thing. I built a script that helps me undo everything in my Editor panels, and you can find it on Unify: EditorUndoManager (it can also manage undo on inspected prefabs). Remember that buttons don’t set Unity’s GUI.changed value to true (which is quite logic), and you’ll have to set your source/s as dirty manually (by calling the EditorUndoManager ForceDirty method).
You’ll also probably want to know when an undo/redo was performed, to immediately repaint your panel. To do that, you can use this code inside your OnGUI method:
1
2
3
4
5 if (Event.current.type == EventType.ValidateCommand && Event.current.commandName == "UndoRedoPerformed")
{
// Undo/redo was performed. Repaint.
Repaint();
}
Dragging stuff into your panel
UnityEditor’s drag and drop events are quite confusing, and the docs are once again totally lacking. To drag stuff from outside your panel, these are the methods you have to implement in your EditorWindow:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 void OnGUI()
{
if (currEvent.type == EventType.DragUpdated) {
// Something dragged from outside your panel
// is currently OVER your panel.
// Here you should check if the dragged types are valid,
// and then show the correct draggin icon with something like:
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
} else if (currEvent.type == EventType.DragPerform) {
// This event is fired if the dragged objects are released over your panel,
// AND you didn't set DragAndDropVisualMode to Rejected.
DragAndDrop.AcceptDrag(); // Accept the drag
// Now you can parse the dragged objects
// and import them using the DragAndDrop class.
}
}



Awesome info man! Very useful. I had a horrible time trying to build my own custom inspectors. In the end I found some stuff I could reverse engineer to figure it all out (at least well enough to be functional). A couple of times I’ve set out to build some utility panels with simple tools, but I couldn’t figure out where to begin.
Thanks Boon. I would’ve wanted to write more (and with more details), but I lost so much time finding a good way to insert code into WordPress, that in the end I rushed with the contents
Anyway, now I’m doing a framework to make editor windows/inspectors more easy/quick (and to allow easy selectable/draggable elements, undo/redo, auto-creation of data files, etc.), so I might write something else when I’m done (and give you the source in case you find it useful).