Creating Editor Windows in Unity

Our game developer Oğuz develops Unity editor tools both at work and in his free time. He finds the lack of resources for editor development rather disturbing, so he decided to create his own series of tutorials. Check out the post below and keep following us for even more!

oguz

For the last decade, Unity has been a great platform for developing games that provides a large number of tools to developers: rendering engine, physics engine, animation systems, audio mixers etc. However, when creating levels or generating in-game data, Unity falls short, because each game is unique and requires different kinds of tools. Thankfully, Unity has an API available to us developers to create our own editor windows, custom drawers and inspector panels. In this series of blog posts, I am going to show you how we develop custom editors in Unity for designers and artists at Gram Games. We will start by creating an editor window, put two panels in it, and then make it resizable. In the next post, we will turn that window into a clone of Unity’s own Console window.

Well then, let’s start! First, we are going to create an empty Unity project and add a folder named Editor under Assets. If you give folders in Unity certain names, it will treat their contents in a special way. Editor is one of those names and the scripts in this folder will become a part of Unity’s own editor. So, then, let’s build an editor window script: go into the Editor folder you just created, right-click, and select Create -> C# Script. You can also select Editor Test C# Script, but we will change all the content anyway, so it doesn’t actually matter. Name your script ResizablePanels and then open it in your favourite text editor (here at Gram Games we prefer Xamarin).

Since this is going to be an editor window, the class should derive from EditorWindow instead of MonoBehaviour. The EditorWindow class resides in UnityEditor namespace, so we will need to add it as well.

Editor windows require a static method to be initialized. In this method, we are going build the window and (optional) give it a title. GetWindow() is an EditorWindow method which creates the window, if it doesn’t exist, or finds and focuses on it if it does.

However, a static method on its own will not be enough, we also need to add a button, or something like it, to let our users open the window within Unity. Thankfully there is already an attribute called MenuItem which adds a menu item to Unity’s menu bar and runs the method it is applied to. So, the following code will create the most basic editor window you can create in Unity.

Here is the menu item:
menu-item

And here is our window that is opened when you click it:
window

In order to draw in this window, we will use the OnGUI() method (yes, Unity’s own editor system still uses the old GUI system and it probably won’t change for a long time). But first, we need two rectangles to define our panels. I will also draw these panels in their own methods, so while we are at it, we should add those methods, too.

Our editor window is starting to shape up. All we need to do now is to draw the panels and check if they work correctly. GUILayout.BeginArea(Rect rect) would create a rectangle area to draw in and GUILayout.EndArea() marks the end. These areas will define our panels. I am also going to add a label in both areas so that we can see how they look.

Well, they seem to be working:

window-2

However, those two panels are set to cover half of the window each, but if we want them to be resizable, they need to have variable heights. So, I am going to add a size ratio variable; this way, when one panel covers a certain amount of the window, the other can cover the remaining part.

OK, both panels have variable heights…but we still can’t resize them! But don’t worry, we are not too far from the final product. Now we just need another rectangle area, so that when the user clicks down there we can start resizing. I am going to add that area just between the two panels. It is going to be 10 pixels tall, because, well, why not? I like 10 (I like 1010! even better :)).

We also need to show the user that the mouse pointer is in the resizing area. EditorGUIUtility.AddCursorRect(Rect rect, MouseCursor cursor) does that, so we are going to use it in our drawing method.

There is one more thing we need to show the user: where the resizing area begins. This is going to look like magic, but I assure you, it is not: we will use one of Unity’s own icons and stretch it and place it so that it looks like a line between upper and lower panels.

Almost finished:

window-3

And now, we will finalize it by adding the actual interaction. We will process the incoming events and if the event is a mouse down event and it is in the resizing area, we will start resizing.

And here is the finished version:

resizable-panels
Click on the image to see the window in action

As you can see, creating an editor window in Unity with resizable panels is fairly easy. In the next blog post we will build on this editor window to create a clone of Unity’s console window.