Creating your own Unity tool from scratch

This blog post will cover the basics of how to setup your project in order to create some custom editors. What is written here applies to all custom editors wether they be Editors, Editor windows, custom property drawers, custom object previews etc.


Unity3D is can be great game engine to work with and it gets more features added all the time. The tooling for Unity is however quite lacking in many areas. Their solution to this is an extensive editor API allowing for custom tools. If you are looking for something, Unity's Assets store and github.com are both full of tools. But what do you do when you cant find what you are looking for? The answer is easy: build your own.


Accessing Unity's Editor API.

For performance and build size reason Unity has chosen to split their API up in several different parts (called Assemblies). The Editor part of Unity is only used when working in the Unity editor and is therefor not included or accessible from normal game play code. All if Unity's Editor classes resides in the

UnityEditor
namespace (the core resides in
UnityEngine
) If you where to create a normal new
MonoBehaviour 
derived class and try access anything in the
UnityEditor 
namespace when you try to build your game you will get an error message saying
The type or namespace name 'Editor' could not be found (are you missing a using directive or an assembly reference?)
In order to get this to work you must place any editor extensions or tools in your project in a folder namned Editor. You can create as many of these as you like and place them wherever you want within your projects asset folder and Unity will pick them up and build them as part of the UnityEditor assembly.


Unity (and all C# projects) builds into C# assemblies. Unity's normal game play code is build into an assembly named
Assembly-CSharp
and only depends on UnityEngine. Any .cs files found in an Editor folder is instead built into a separate assembly named
Assembly-CSharp-Editor
and depends on
UnityEngine
,
Assembly-CSharp
(you can access any code and classes you written as part of the gameplay code) as well as
UnityEditor
.


Different editors and what they do:

EditorWindow

Creates a new whole editor window for Unity. Has nothing to do with the inspector window. Useful for when making custom tools from scratch.

using UnityEngine;
using UnityEditor;

public class ToolsWindow : EditorWindow  {
  // This hooks a menu option to Window -> ToolsWindow, running this static method when pressed
  [MenuItem("Window/ToolsWindow")]
  public static void ShowWindow()
  {
    // This get or creates an instance of this editor window and displays it.
    var window = GetWindow<ToolsWindow>();
    window.titleContent = new GUIContent("Custom Editor");
  }
  
  void OnGUI()
  {
    // TODO: Write your custom editor window here
  }
}

Editor windows can be used in several different ways. The above example creates a "normal" window that exists until manually closed. You could hook custom editor windows to property drawers if you want very special property drawers for some type.


Editor

Overrides how a specific

MonoBehviour 
or
ScriptableObject 
script is displayed in the inspector window. Useful for when the entire behaviour needs a custom editor. Is used by creating a new class inheriting from
Editor 
and then using the
CustomEditor 
attribute to tell Unity what class it's supposed to be the editor for.


The following class will be displayed as an inspector window for the

ToolsWindowSet 
MonoBehaviour.

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(ToolsWindowSet))]
public class ToolsWindowSetEditor : Editor
{
  public override void OnInspectorGUI()
  {
    // TODO: Write your custom editor here
  }
}

I personally usually suggest avoiding using custom Editors, instead using custom property drawers, unless you really have a need to replace the entire inspector window for the object.

Property Drawer

Property drawers are used to override how a single property of an object is displayed in the inspector. This is usually preferred over creating a whole new Editor. Property drawers are not reserved to Unity Objects. You can create a bare C# class, give it the

[System.Serializable]
and then give it a custom property drawer.


This section created a custom property drawer being shown whenever a property of the type SerializedList is used in a Unity object.

using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(SerializedList))]
public class SerializedListPropertyDrawer : PropertyDrawer
{
  public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  {
    // TODO: Write how this property should be displayed
  }
}

The advantage of a property drawer over a custom editor is that you can have a specific field type you always want to be a displayed in a specific way, no matter where and how many times you put it your project. By using a property drawer you only have to define how these are displayed once.