Have you been wondering how Unity Developers created those systems or plugins that you have downloaded from the assets store? We're not going to lie but we do too actually.We've been doing research on how to create our own plugins and to be honest, it's not THAT really complicated at all.All you really need honestly is to create a C# script and add a few lines of code that creates the menu and the window, and... it's all up to you what you're going to put in the custom window that you created.However, if you're not really sure what we're talking about here then don't worry. We're here to help you out.In this tutorial, we're gonna be looking at how to create your very own custom editor window that you can use to speed up your game development process. Getting Started For this tutorial, we don't really need to set up a scene. All we need is a C# script and that's it. Note: It's a good practice to always separate your custom editor scripts from your game scripts. Most developers put these scripts in the Editor folder. Important: Scripts inside the Editor folder will not be included in the builds. That's why it's important to NOT reference your custom editor scripts to your game scripts. Creating the Custom Editor Create a new C# script and name it CustomUnityEditor.cs and copy the following code: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { } Notice that our code above is different from your usual scripts.Normally we use the namespace UnityEngine to get almost everything that we need to program our game. However, this namespace never gives you the ability to extend Unity, that's why we added UnityEditor. This namespace will allow us to almost control everything inside Unity.Now, since we don't really want this script to only process once it's applied to a game object, we had to change it from MonoBehaviour to EditorWindow. This will hint Unity that this script is a custom editor script and will always run throughout the editor.Now the next thing we're going to do is to create a menu.Open the CustomUnityEditor.cs script once again and update its code to the following: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { } } For the update above, we just simply created a custom menu using the MenuItem attribute. The MenuItem attribute allows you to add custom menu items to the main menu and the inspector context menus.But after using the MenuItem attribute, you must include underneath it a function that will run once you have clicked the menu. That's why we added the function CustomEditorWindow().Save the script and head back to Unity. Once the script is saved, you should be able to see the custom menu in Unity like in the above image. Clicking the Run option though will not do anything at the moment. This is obviously because we have no process yet inside your CustomEditorWindow() functon.Now let's start creating the custom editor window.Open the CustomUnityEditor.cs script once again and update its code to the following: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } } In the update above, we just added the GetWindow() to render a custom editor window. Basically, what GetWindow() will do is it will check if the CustomUnityEditor type already exists in Unity. If it does, then open the editor window. Otherwise, create and show a new one and return its instance of it.Save the script and you should be able to create your own editor window. Graphical User Interface Now that we have our custom editor window working, it's time for us to add content inside this window.To do that, we'll have to use the built-in function OnGUI(). You probably remember this but back in the day, OnGUI() is used to draw buttons, labels, and other user interfaces in the game but ever since the new UI system is added to Unity, OnGUI() becomes something that you only use for the editor.Let's head back to our script and update its code to the following: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { } } GUI Labels To create a label for your custom unity editor, all you need to do is to use GUILayout.Label() function: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor"); } } This should give you the following: If you want to add styles to your labels, all you need to do is to use EditorStyles as the second argument for Label(). using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); } } This should give you the following: GUI Space There are instances that you find the content of your editor, a bit, cramped and so Unity provided a way that allows you to give spaces between your elements. using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); } } GUI Text Field The most commonly used for custom editors is the text field. This allows you to modify any value that your game objects are holding.Keep in mind though that working with text fields is a little bit different. Instead of using GUILayout, you will have to use EditorGUILayout. using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); _name = EditorGUILayout.TextField("Name", _name); } } For text fields, it's important to dedicate and create its own variable to assign the value of the text field. Also, make sure that whenever you create the variable, it's value is initialized. Otherwise, you will get a null-value error. GUI Color Also one of the most commonly used elements. The process of adding color picker into your editor is pretty much the same with creating a text field. The only difference is instead of making a string (or int, float, etc) variable, you use Color. using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; private Color _color; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); GUILayout.Label("Name your object(s)", EditorStyles.boldLabel); _name = EditorGUILayout.TextField("Name", _name); GUILayout.Space(_space); GUILayout.Label("Pick a color for your object(s)", EditorStyles.boldLabel); _color = EditorGUILayout.ColorField("Color", _color); } } This should give you the following: GUI Toggle Creating a toggle for your custom editor is also very simple. Just create boolean variable and use Toggle() function: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; private Color _color; private bool _active = false; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); GUILayout.Label("Name your object(s)", EditorStyles.boldLabel); _name = EditorGUILayout.TextField("Name", _name); GUILayout.Space(_space); GUILayout.Label("Pick a color for your object(s)", EditorStyles.boldLabel); _color = EditorGUILayout.ColorField("Color", _color); GUILayout.Space(_space); GUILayout.Label("Is the object(s) available in the scene?", EditorStyles.boldLabel); _active = EditorGUILayout.Toggle("Toggle", _active); } } This should give you the following: GUI Button Buttons are one of the most useful things that you can add to your editor. To add a button to your editor, all you need to do is to use GUILayout.Button() as an argument for an if statement. using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; private Color _color; private bool _active = false; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); GUILayout.Label("Name your object(s)", EditorStyles.boldLabel); _name = EditorGUILayout.TextField("Name", _name); GUILayout.Space(_space); GUILayout.Label("Pick a color for your object(s)", EditorStyles.boldLabel); _color = EditorGUILayout.ColorField("Color", _color); GUILayout.Space(_space); GUILayout.Label("Is the object(s) available in the scene?", EditorStyles.boldLabel); _active = EditorGUILayout.Toggle("Toggle", _active); if(GUILayout.Button("Proceed")) { } } } This will allow you to send a process once the button is clicked. Now, the question is...How do you actually use these elements to control and modify your game objects?There are two ways to do that: Using GUILayout.Button()Using events Using Buttons for Unity Editor Let's start first with the button. Let's make it work like whenever we press the button, the name of the game object that we selected will be replaced by the value of _name. The color of the game object will be replaced with _color, and the availability of the game object will be controlled by the toggle.Open the editor script once again and update its code to the following: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; private Color _color; private bool _active = false; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); GUILayout.Label("Name your object(s)", EditorStyles.boldLabel); _name = EditorGUILayout.TextField("Name", _name); GUILayout.Space(_space); GUILayout.Label("Pick a color for your object(s)", EditorStyles.boldLabel); _color = EditorGUILayout.ColorField("Color", _color); GUILayout.Space(_space); GUILayout.Label("Is the object(s) available in the scene?", EditorStyles.boldLabel); _active = EditorGUILayout.Toggle("Toggle", _active); if(GUILayout.Button("Proceed")) { GameObjectRename(Selection.gameObjects); } } private void GameObjectRename(GameObject[] objects) { foreach (var obj in objects) { obj.name = _name; } } } In the updated code above, we added a function that when we pressed the GUI Button, all of the selected game objects will be given a new name.In order to do that, we'll have to loop through all of the selected game objects in our editor. Luckily, we have what's called Selection.Selection is one of the most useful classes in UnityEditor. One of its use is to allow you to access all of the selected game objects in the editor.Like in the code above, we have used Selection.gameObjects. This will provide us all of the game objects that we selected in the editor.We also created a function GameObjectRename(). Since we're passing an array of game objects, we'll have to create its parameter to be an array.Inside this function, we loop through all of the selected game objects and each game object will get a new name.So if you save the script and head back to Unity, you should be able to rename all of the game objects in your scene. Using Events for Unity Editor Now that we're able to change the name of our game objects on click of a button. How about changing the names of our game objects when we change the value of the elements of our custom editor? You know? Like the inspector. When you adjust the position of the game objects, the game objects move as well without hitting a button.In order for us to do that, we'll have to use two functions that will check if any of our editor GUI is being updated.Let's take a closer look. Have your editor script updated to the following: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; private Color _color; private bool _active = false; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { EditorGUI.BeginChangeCheck(); GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); GUILayout.Label("Name your object(s)", EditorStyles.boldLabel); _name = EditorGUILayout.TextField("Name", _name); GUILayout.Space(_space); GUILayout.Label("Pick a color for your object(s)", EditorStyles.boldLabel); _color = EditorGUILayout.ColorField("Color", _color); GUILayout.Space(_space); GUILayout.Label("Is the object(s) available in the scene?", EditorStyles.boldLabel); _active = EditorGUILayout.Toggle("Toggle", _active); if(GUILayout.Button("Proceed")) { GameObjectRename(Selection.gameObjects); } if(EditorGUI.EndChangeCheck()) { Debug.Log("Value changed"); } } private void GameObjectRename(GameObject[] objects) { foreach (var obj in objects) { obj.name = _name; } } } In the updated code above, we added two things. One is the BeginChangeCheck() function and second is the EndChangeCheck() function. The first function will obviously start checking if something in the editor is being updated. However, when you use this function, you have to make sure that you end this with an EndChangeCheck() function and this function should be used as an argument for an if statement.Everything that is between this two functions will be checked if something is changing.Inside the if statement is where you can add functions when the editor found something changed. Now you may be asking.How do we actually know if a certain element changed?The answer is actually pretty simple.You will have to compare the value of the previous element to the current value of the element. If the values are not the same then that means they're meant to be updated. Otherwise, they're not.Alright, let's try that.Update the editor script to the following: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; private Color _color; private bool _active = false; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { EditorGUI.BeginChangeCheck(); var oldName = _name; GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); GUILayout.Label("Name your object(s)", EditorStyles.boldLabel); _name = EditorGUILayout.TextField("Name", _name); GUILayout.Space(_space); GUILayout.Label("Pick a color for your object(s)", EditorStyles.boldLabel); _color = EditorGUILayout.ColorField("Color", _color); GUILayout.Space(_space); GUILayout.Label("Is the object(s) available in the scene?", EditorStyles.boldLabel); _active = EditorGUILayout.Toggle("Toggle", _active); if(GUILayout.Button("Proceed")) { GameObjectRename(Selection.gameObjects); } if(EditorGUI.EndChangeCheck()) { Debug.Log("Value changed from: " + oldName + " to " + _name); } } private void GameObjectRename(GameObject[] objects) { foreach (var obj in objects) { obj.name = _name; } } } In the updated code above, we simply cached the old value of our _name variable to oldName. Then, right after the change check, we will check if the old name is the same as the new name. As you can see from the image above, we have the old value and the new value. Awesome!Now, the reason why we've done the checking it's because Unity currently doesn't have a function to tell us which data is being changed. It's just to give you an idea of how you can cache your old values.However, the case for the game objects is different.We have to check if the current name of the game object is not equal to the new name. Head back to the script and update it to the following: using UnityEngine; using UnityEditor; public class CustomUnityEditor : EditorWindow { private float _space = 20f; private string _name = ""; private Color _color; private bool _active = false; [MenuItem("Custom Editor/Run")] public static void CustomEditorWindow() { GetWindow<CustomUnityEditor>("Custom Unity Editor Window"); } private void OnGUI() { EditorGUI.BeginChangeCheck(); var oldName = _name; GUILayout.Label("Welcome to your very own editor", EditorStyles.largeLabel); GUILayout.Label("This is a label with no styles at all. Feel free it experiment with me and learn how to display user interfaces"); GUILayout.Space(_space); GUILayout.Label("Name your object(s)", EditorStyles.boldLabel); _name = EditorGUILayout.TextField("Name", _name); GUILayout.Space(_space); GUILayout.Label("Pick a color for your object(s)", EditorStyles.boldLabel); _color = EditorGUILayout.ColorField("Color", _color); GUILayout.Space(_space); GUILayout.Label("Is the object(s) available in the scene?", EditorStyles.boldLabel); _active = EditorGUILayout.Toggle("Toggle", _active); if(GUILayout.Button("Proceed")) { GameObjectRename(Selection.gameObjects); } if(EditorGUI.EndChangeCheck()) { //Debug.Log("Value changed from: " + oldName + " to " + _name); GameObjectRename(Selection.gameObjects); } } private void GameObjectRename(GameObject[] objects) { foreach (var obj in objects) { if(obj.name != _name) obj.name = _name; } } } The update is just super simple. Inside the GameObjectRename() function, we checked if the current value of the game object's name is equal to the value of _name. If it's true then we change the name of the game object. Otherwise, don't.Going back to Unity should allow you to update the names of the game object without pressing the button. Conclusion There you have it! We hope this lesson gave you a bit of a lesson on how to create a custom editor for Unity. We know we have left a few things in this lesson. We've seen that this is a long process and so we'll separate the lesson for the game object colors and other controls.For now, we hope you enjoyed your reading and we hope you learned from us. However, if you encountered any issues that we haven't seen, please let us know and we'll help you as soon as we can.