Friday, September 28, 2012

Custom Windows In The Unity Editor

People who don't use Unity are not going to get much out of this post.  If you don't find coding interesting, feel free to ignore this one.

The Unity documentation isn't very clear on how to setup scripts to add features to itself.  I found it rather confusing.  This is mostly because the biggest step, where to put the script file to make it work, isn't explained very well.  I aim to help some of you out with this post, having got it working this afternoon.

When setup right, having the Editor scripts folder and hooking code into the Unity Editor interface is very powerful.  Such a setup allows one to write custom tools.  In short, everything in the Unity graphical user interface(GUI) that you use to make your game project is written in Unity.

A quick disclaimer:  I am no expert on Unity.  I've got less then a year's experience using the tool, so don't take my words as law.  If you found this page in a google search, I'm probably about as experienced as you.

Anyway, enough rambling.  On with the useful info (after the break):

The biggest issue I had, as stated earlier, was where this Editor folder went.  The manual isn't that clear if it goes in your project's base directory, or in the Assets folder.  It's also not clear if sub directories work or not due to not stating this vital information anywhere I could find in the manual itself.

The correct way to set this Editor folder up is to have Unity open, right click the Project file list, and create a new folder called "Editor" in there.  You technically could create this outside Unity and then let Unity find it on next refresh, but it's better to just make the folder using Unity itself to save the trouble.

In Unity, the folder will look like "Editor".  It will be sitting outside of all the other folders, in the main Project panel of the interface.  Your GUI editor scripts all go in there.

Outside Unity, the directory structure should be:

Project Folder/Assets/Editor

Now that you have the folder setup, any scripts you toss into it will run during the time Unity's editor interface is open.  You should be able to type up and toss the example scripts from the manual into that folder to see for yourself.

And yes, sub directories work just fine.  Any scripts in sub directories, so long as they are within the "Editor" directory, will still work.  So you can sort your tool scripts nicely if you make tools that have more then one script to run.

The Unity documentation on writing editor scripts is here:


However, it's a bit confusing and messy, and also expects you to read up on the editor GUI scripting in depth, so here's a script example I hacked together from two of their examples:

-------------------------


//Example Simple Window
// by Gawain Doell, 2012
// Some code borrowed from the Unity manual examples.
//
// Save this code into this path to make it work:
// Project Folder/Assets/Editor
//
// The script must be named SimpleWin.js
// Any other name will throw an error.

// we extend the EditorWindow class, this allows
// us to create a new window that does what we want
// to do.

class SimpleWin extends EditorWindow {

//We'll create a string, and a few true/false flags to show how useful
// this can be.  These values are attached to our editor window interface.
var myString = "Hello Everyone";
var myBool = true;
var myFloat = 1.23;

//add menu named Simple Window to Window Menu
@MenuItem ("Window/Simple Window")

static function ShowWindow () {

//Get existing open window or if none, make a new one
//The EditorWindow.GetWindow function takes care of making the
// window if it doesn't exist yet, and if it does, Unity's
// default behavior will be to grab the existing window.

EditorWindow.GetWindow (SimpleWin);

//The "SimpleWin" part of the above line tells Unity which script
// in the Editor folder to spawn.  It must be the name of
// a valid Editor Script, or Unity will toss an error.
//For example, if you save this script as Foo.js instead of
// SimpleWin.js, you would have to edit the above to say
//
// EditorWindow.GetWindow (Foo);
//
}

function OnGUI () {
//actual window code goes here

//Anything supported by a normal OnGUI event can go here
//The main difference is we want to use the
//EditorGUILayout object instead of the in game GUI.

//Show a label with our custom string in it
GUILayout.Label ("Base Settings", EditorStyles.boldLabel);
myString = EditorGUILayout.TextField ("Text Field",myString);

//Show a Editor checkbox that allows us to
//control the value of myBool
myBool = EditorGUILayout.Toggle ("Toggle",myBool);

//Show a slider to allow us to set
//myFloat to anything we want
myFloat = EditorGUILayout.Slider ("Slider",myFloat,-3,3);
}
}

-------------------------

Save that script to your editor folder as SimpleWin.js, and you'll now be able to find your new window tool in the Unity Editor, located under the Window menu.

As you can see, you can do a lot with this.  The editor scripts can have functions attached to them, they can also access things currently selected in the editor.  Everything the Inspector window in Unity accesses can be read and edited by your own tools as well.  And of course, all Unity Script stuff can be used in these scripts too.

In theory, you can turn the Unity editor into a very customized level editor, specific to each project you have.  The best thing is that if you have multiple projects, you can make Unity "adapt" to each project because the Assets/Editor folder is part of the project folder.

I hope this small example has proven useful in any case for getting you started.

I've just started playing with this myself to make some tools for measuring things for levels in a 3d platformer.  If I get some of the tools solid/generic enough, I'll see about sharing some on this blog later.

Gawain, signing off.