Learn Unity Editor Scripting: Component Inspector Editors (Part 3)
In this post we will learn how to create custom inspector editors for different components (our
ScriptableObject). You can tell Unity Editor how exactly you want the Inspector UI for your components to look like.
This article is part of a series in which I explain all the techniques for extending the Unity Editor. See the overview post here.
Prerequisite: You need to know C# programming and be familiar with Unity Editor to benefit most from this post. You also need to be familiar with Unity’s IMGUI. I’ll make a tutorial on IMGUI soon. Until then, you can refer to Unity documentation.
There is an accompanying Unity project. I highly recommend downloading it and trying the topics as you read them here. Seeing the examples in action makes them stick to your brain.
This is the acompanying repository for my series on Unity Editor Scripting. You can find the articles down below. In…
For instructions on how to get started with the project, see the overview post.
Without further ado, let’s jump in!
1. Custom Editor for GameManager Component
We are going to create a custom editor for the
GameManager class. With a custom Editor we can show our own GUI in the inspector window for our components. In the project, select the “Manager” object and note how the inspector UI looks like for it. The manager object is a singleton and manages the UI and victory / lose conditions.
1.1 Implement the Default Inspector
Similar to Property Drawers in the previous post, we need to create a new “Editor” class (script file should be in an Editor folder) which performs drawing the GUI in inspector. We also need to add an attribute to it so that Unity knows it will be responsible for drawing the inspector GUI for the
- Our editor class needs to extend the
- We can name the class anything. I prefer the
CustomeEditorattribute in line 1 tells Unity to use the class for showing GUI for the
GameManagercomponent in Inspector window.
- We should override
OnInspectorGUIwhich responsible for the GUI of the component in Inspector window.
DrawDefaultInspectorhelper function draws the default GUI for the component.
- Again we have added a
HelpBoxat the end to make sure we are seeing our custom editor in Inspector window not the default one.
OnInspectorGUIgets called for each draw of the Inspector GUI for the component. Typically that happens a few times per second, so make sure this method is lightweight. It affects the performance of the Unity Editor.
1.2 Add Validation UI
Next, let’s add a validate button to the inspector. The validation will tell the developer if there are errors in the scene setup. That way if multiple developers are making levels for the game, they will know how to setup the level properly.
OnEnablecallback gets called for every new component Inspector. Just like the
MonoBehaviours, it is the perfect place for performing any one time setup.
targetfield has a reference to the component our editor is handling.
- We are using two styles
styleInvalidwith different text colors for when the scene setup is valid or invalid.
OnEnablewe setup the styles and cache the target
GameManagerour editor is handling.
OnInspectorGUI(lines 21 to 30) we add the validate button and show the result of the scene validation.
The validation logic resides in GameManager.cs file. In Unity remove the player tag from the Player game object in the scene and select the Manager object. The inspector should show the error in red like the right image.
After fixing every setup error, then the validation UI should show “All Set!” in green text.
1.3 Custom GUI for a Property of the GameObject
So far we have learnt how to create custom Inspector UI for a component, access the backing component directly. Next let’s make changes to the component from the Editor.
DrawDefaultInspector helper did all the heavy lifting for us.
Let’s create a custom UI for the
levelName field. Instead of the default textbox, which let’s the developers choose any random name, we show an int dropdown and set the name from the number selected from the dropdown. This way we make sure the level names will always be in Level X format.
We already know how to create the GUI using IMGUI and how to write values to serialized properties from the previous post on how to write property drawers. With serialized objects such as components, things are a little more complex. We have two ways to modify our objects:
- By modifying the serialized properties and serialized objects.
- By modifying the
We will see how to use both options in the next two subsections.
1.3.1 Using the Serialized Object and Serialized Properties
Here is the new code for showing our new custom UI for the
levelname field and writing the changes back to the serialized property and serialized object.
This is the preferred method of writing custom editors. It makes it easier to handle multi-object editing and undo / redo.
Only the additions to the class are shown here.
levelfields are created for showing the dropdown in IMGUI.
serializedObjectfield of editor class gives us a reference to the object we are modifying.
serializedObject.Updatesyncs up the serialized properties in the object with the game object we are modifying. We should call this before making any changes to make sure our values are the most up to date ones.
serializedObject.FindPropertylet’s us find the properties of the game object we are modifying.
serializedObject.ApplyModifiedPropertieswrites the changes we have made to serialized properties back to the game object. If you comment out this line, the changes made through inspector will not take effect!
Here is how the Inspector looks like:
Everything works fine excepting for
levelName field being shown twice. One time by our custom GUI code. Again by the call to
DrawDefaultInspector. Luckily we can fix this by adding the
HideInInspector attribute to the field as we learnt in part 1. That way the default inspector will hide the
Now the UI looks just how we wanted it!
1.3.2 Using the Component Directly
Now let’s modify the
OnInspectorGUI method to write the changes back to the component directly, bypassing the serialized object. This may seem more straightforward but needs care as we need to tell Unity what changed which is more prune to errors in my experience. At the end of the day it is your choice which way to go.
From before, replace the Level Name Section of
OnInspectorGUI method with the following.
Undo.RecordObjecttells Unity Editor that the object is being modified. Unity Editor will make a snapshot of the object at this point. At the end of the
OnInspectorGUIcall, Unity Editor will diff the modified object from the snapshot and if there are changes mark scene dirty and add an action to the undo stack.
The UI looks exactly as before and behaves the same. We now have our own action on the undo stack with the label we provided to
1.4 Multi-object Editing from Our Custom Editor
The custom editors can by default only modify a single object. Let’s create another custom editor, this time for our
Create a file named TargetControllerEditor.cs under the Scripts/Editor folder with this content. (You need to add
using s at the top).
Now when a single object is selected, the Inspector shows just fine. But when we select multiple objects (Cubes from the sample scene), the Inspector tells us that “multi-object editing is not supported”.
We can tell Unity that our custom editor can handle multi selection by using the
Now the Inspector works just fine. Again we are relying on the magic from
DrawDefaultInspector . Let’s get rid of that and implement our own GUI to learn how to handle serialized properties that represent multiple objects.
SerializedPropertycan represent properties from multiple objects.
serializedProperty.hasMultipleDifferentValueschecks to see if all values from the property are the same or not. We use this check in line 7 to show different GUI.
- We use <multiple values> magic string to mean there are multiple values. If the user changes the value from this, then we write the new value to the property, which will modify it for all the selected objects.
Our UI looks and behaves similar to the default inspector UI.
In this post we learnt:
- how to create our own Inspector GUI in Unity Editor and use them for our components. We can show our custom UI, add validation and other things with custom editors.
- We also learnt how to write the changes from Inspector back to the objects.
If you have any questions and suggestions about this post, feel free to leave a comment.
Follow me to get notified of my new posts. I am an indie game developer and regularly write tutorials, tips and tricks and stories about game dev, programming and Unity.
If you find this tutorial useful, please support me on Patreon. It takes a good amount of time to write these tutorials and your support will keep me going. Thank you!
Next we will learn how to create menu items both in the inspector context menus and in the main Unity menus (ETA Oct 28th 2020).