Unity Custom Inspectors Tutorial: Getting Started
In this tutorial you will learn how to create Custom Inspectors in the Unity Editor. From editing how your components look, to adding Editor windows :] By Gur Raunaq Singh.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Unity Custom Inspectors Tutorial: Getting Started
25 mins
- Introduction
- Getting Started
- Requirements
- Exploring starter Project
- Basic Customizations
- Header Attribute
- Range Attribute
- Space Attribute
- Tooltip Attribute
- HideInInspector and SerializeField
- ContextMenu Attribute
- Extending the Inspector
- Editor Scripting
- Custom Form
- Buttons with Image as Thumbnails
- Creating custom Windows
- Where to Go From Here
Buttons with Image as Thumbnails
In the previous sub-section, you learned how to add additional components such as a TextField and Button to extend the capabilities of the Inspector. However, GUILayout.Button()
also lets you specify an image thumbnail for a button in place of plain text.
A typical use case for something like this might be to have buttons to easily spawn different kinds of Prefabs that you might have in your project for easy experimentation, or during level building.
Go back to TankControllerEditor.cs and add the following piece of code after //Custom Button with Image as Thumbnail
:
//Custom Button with Image as Thumbnail
//1
GUILayout.Space(20f);
GUILayout.Label("Spawn Prop");
GUILayout.BeginHorizontal();
//2
if (GUILayout.Button(Resources.Load<Texture>("Thumbnails/Board_Thumbnail"),
GUILayout.Width(thumbnailWidth), GUILayout.Height(thumbnailHeight)))
{
tank.SpawnProp("board"); //3
}
if (GUILayout.Button(Resources.Load<Texture>("Thumbnails/OilDrum_Thumbnail"),
GUILayout.Width(thumbnailWidth), GUILayout.Height(thumbnailHeight)))
{
tank.SpawnProp("oil_drum");
}
if (GUILayout.Button(Resources.Load<Texture>("Thumbnails/Crate_Thumbnail"),
GUILayout.Width(thumbnailWidth), GUILayout.Height(thumbnailHeight)))
{
tank.SpawnProp("crate");
}
if (GUILayout.Button(Resources.Load<Texture>("Thumbnails/TrafficCone_Thumbnail"),
GUILayout.Width(thumbnailWidth), GUILayout.Height(thumbnailHeight)))
{
tank.SpawnProp("traffic_cone");
}
if (GUILayout.Button(Resources.Load<Texture>("Thumbnails/Wheel_Thumbnail"),
GUILayout.Width(thumbnailWidth), GUILayout.Height(thumbnailHeight)))
{
tank.SpawnProp("wheel");
}
GUILayout.EndHorizontal(); //4
This is fairly straightforward:
-
GUILayout.Space
is added to give extra vertical space. A label is added to increase readability, andBeginHorizontal()
is called to set the layout group as horizontal. - Similar to the previous subsection, a
GUILayout.Button
is declared with the following arguments: a texture for thumbnail is specified usingResources.Load
, thumbnail width and height is specified using("Thumbnails/Board_Thumbnail") GUILayout.Width(ThumbnailWidth)
andGUILayout.Height(ThumbnailHeight)
respectively. - The block of code inside the
if
gets executed when the button is clicked. In this case, theSpawnProp()
method defined in TankController.cs is called with the name of the prop as an argument. The reference to the TankController.cs script comes from the previously set-uptarget
near the top of theOnInspectorGUI()
method. Similarly, four more buttons — 1 for each prop — are declared as part of the horizontal layout group. - GUILayout.EndHorizontal() is called to end horizontal group.
Save the changes, and look at the Inspector again.
You can now easily spawn props in your scene without fiddling with the built-in menus. In general, you can use this approach to create any custom functionality:
- Define a button.
- Specify Text or Texture
- Add code to execute on button click.
Creating custom Windows
In the previous sections you learned how to:
- Improve readability and organization of public fields in the Inspector.
- Extend the capabilities of the Inspector for a given component using Editor scripts.
Just like there are many different types of built-in windows within the Unity editor (Project, Hierarchy, Console, etc.), you can create your own custom windows using the EditorWindow namespace.
From Assets \ RW \ Editor open CustomWindow.cs and add the following code after // Define Menu item and add reference to Window
:
// Define Menu item and add reference to Window
[MenuItem("Custom/Colorizer")] //1
public static void ShowWindow() //2
{
GetWindow<CustomWindow>("Colorizer"); //3
}
Here’s the breakdown:
- The MenuItem constructor is called, which creates a menu item. The static method following it is called when the menu item is selected. In this case
Custom/Colorizer
is used to specify that a new item Custom will be added in the status bar and an item name Colorizer will be used to open the window. - The static method
ShowWindow()
is declared. -
GetWindow
from the EditorWindow class is called, which returns an EditorWindow of type t (CustomWindow in this case) with the title of window as “Colorizer”.(string Title)
Save the script and go back to the editor.
You’ll now see a new menu item added in Unity.
Click on Colorizer, and you’ll have a new window open.
Ready to add some items to the window?
Add the following code in CustomWindow.cs after line comment // Define items to be displayed in the Window
:
// Define items to be displayed in the Window
void OnGUI() //1
{
GUILayout.Label("Color the selected Objects", EditorStyles.boldLabel); //2
color = EditorGUILayout.ColorField("Color", color); //3
if (GUILayout.Button("Colorize!")) //4
{
Colorize();
}
}
// Method to set Color
void Colorize()
{
foreach (GameObject obj in Selection.gameObjects) //5
{
Renderer renderer = obj.GetComponent<Renderer>(); //6
if (renderer != null)
{
renderer.sharedMaterial.color = color; //7
}
}
}
Looking at this code block step-by-step:
-
OnGUI()
is called, which allows you to implement your own editor GUI. - A GUILayout label is added.
- The
EditorGUILayout.ColorField
makes a field for selecting a color and returns the color which is saved in the variablecolor
. - A GUILayout button is added to call
Colorize()
. - Before you can set a color, you have to select the GameObjects in the Hierarchy window. Once selected, this line iterates through all of the selected GameObjects.
- A reference to the Renderer component is saved in the variable
renderer
. - If a Renderer component is attached to the selected GameObject, the material color is set.
Save the script, and then open the Custom Window Colorizer again.
Select a few different types of GameObjects in the scene such as the cones or crates. Choose a color from the color selector in the Colorizer and click Colorize!. Voilà — all of the GameObjects that you selected are colorized! :]
Have a quick play of the level after colorizing some barrels and crates and test things out.
That’s it! You’re done, and look at everything you’ve learned in this tutorial:
- How to customize the look and feel of the public fields in the Inspector.
- How to extend the Inspector to add your own custom GUI components.
- How to create a custom window to superpower your development setup.
Where to Go From Here
Congratulations on making it to the end!
This goal of this tutorial was to give you an idea of some of the cool ways to customize your Unity development setup.
As always, you can find the final project using the “Download Materials” link at the top or bottom or this tutorial.
But don’t stop here! There are many more ways to customize Unity. In particular, you should check out:
- UnityEngine.CoreModule.
- GUILayout class.
- Methods defined in EditorGUI class such as DropdownButton, CurveField, HelpBox, etc.
- Make editor wizards using ScriptableWizard class.
If you have any questions or comments, or you want to show what you experimented with from the learnings of this tutorial, join the discussion below!