Welcome back to my series on making Custom Editors in Unity3D. Until now, we’ve been looking at ways to customize and add information to the editor without much custom code, but today we’re going to start getting into the nitty gritty of the tools we’ll be using in the UnityEditor namespace.
The first thing of note when you want to start writing code for custom editors of any kind in Unity3D is that they require a certain folder structure to work. Specifically, any file that contains a custom editor or uses the UnityEditor namespace need to be under a folder named ‘Editor’. The ‘Editor’ folder can be anywhere in the folder structure above the relevant file (so you could have Assets/Editor/MyCustomEditors/MyCoolCustomEditor.cs, or Assets/MyCustomClass/Editor/MyCoolCustomEditor.cs, either would work).
Note: Files under an ‘Editor’ folder are not accessible or able to be referenced by files outside of an ‘Editor’ folder, but files in an ‘Editor’ folder can access any other files in the project that a script could normally access. These actually get split into two separate projects in MonoDevelop/Visual Studio.
The primary classes we’ll be doing to actually get functionality out of our Custom Editors are the EditorGUI and EditorGUILayout classes. These function very similarly to the GUI and GUILayout classes, if you’re familiar with them (GUI and GUILayout will actually work in an editor script, but EditorGUI and EditorGUILayout have additional fields that are editor specific, so I tend to use them as much as possible). The only difference between the two is that EditorGUI requires a Rect parameter to specify where to draw the control, while EditorGUILayout will automatically layout your components for you – I tend to use EditorGUILayout as much as possible since it makes life easier, but EditorGUI works just as well if you want to have more control over positioning of your controls.
The primary functions we’ll be dealing with in EditorGUI are the [Type]Field() functions (i.e. FloatField, IntField, ColorField), which as you might imagine, are what you use to draw and get data of various types of the editor. Their usage is as follows:
//For different value types, use the various other Field functions //such as IntField for ints, ColorField for Colors, etc float newValue = EditorGUI.FloatField( Rect position /*if you're using EditorGUI*/, string label, float currentValue);
If you’re using EditorGUI, position will tell the field where to draw
label is the string that will display as the field’s label (who would have thought!)
currentValue is the current value of the variable, and the function returns a value representing what came back from the editor field (currentValue if nothing changed, or the newly entered value if the user changed it)
For example, if we wanted to edit an instance variable of type integer that was called tileIndex, we would use the following:
tileIndex = EditorGUILayout.IntField("Tile Index", tileIndex);
The one somewhat commonly used field which works slightly differently is ObjectField, used for anything derived from UnityEngine.Object (this includes GameObjects and MonoBehaviors). ObjectField has two additional parameters:
Type targetType – used to specify the type of Object to allow (It will also accept any subclasses of the specified type)
bool allowSceneObjects – Specifies whether or not objects from the scene are allowed to be assigned to this field (I generally always set this to true, unless the object being edited is a custom asset).
As I mentioned earlier, EditorGUI and EditorGUILayout are functionally similar, the main difference being that EditorGUI requires you to specify the position of your controls, while EditorGUILayout lays them out for you. You control how EditorGUILayout lays out your controls with the BeginHorizontal(), EndHorizontal(), BeginVertical() and EndVertical() functions. These functions need to be paired (every BeginHorizontal() needs to have a matching EndHorizontal(), same for Vertical), and any EditorGUILayout calls in-between them will be laid out either horizontally or vertically (in most cases, your editor code comes ‘pre-wrapped’ in a Begin/EndVertical() pair, and by default fields will be laid out vertically).
Those are most of the basic tools we’ll need to be able to make custom editors in Unity. Next time we’ll start with our first actual custom editor and take a look at how to write a PropertyDrawer!
If you have any questions, comments, or suggestions about anything in this post or other things you’d like to see covered, feel free to leave them in the comments below!