Making a basic 2D tile map editor using a custom inspector


Click To Download Full Source Code

Custom inspectors help you to change the way the inspectors look and work. They also allow you to add a lot of flexibility and certain behaviours to your regular inspectors.

We’ll create a custom inspector and make a very basic 2D tile map editor using the same. Map editors or levels editors are tools that are used to quickly create map layouts for level design. They can be used for prototyping a level too. Although, there is a plethora of map editors already available on the asset store and Unity is already working on their own version, creating one yourself will help you learn the basics of Editor scripting in Unity.


We’ll start in a new, empty scene. Create a new game object and call it “Map Editor”. Create a new C# script, name it “Map”, and attach it to the newly created game object. Remove the Start() and Update() methods. We won’t be needing them.

The Map.cs script should look like this:

Create a new Folder named “Editor” in the Assets folder. Scripts put inside this folder will be treated as editor scripts which help add functionality to the Unity editor and hence these scripts are not included in the final, finished game.

Inside the editor folder, create another C# script and call it “MapEditor”. Remove the Start() and Update() methods from this one as well. Also, since this is an editor script, it needs to extend from the “Editor” class instead of the “MonoBehaviour” class. You’ll need to add the UnityEditor namespace at the top.

We also want this script to know what class the Editor is being used for. It can be done by adding the “CustomEditor” attribute to the class with the name of the MonoBehaviour class as the type.

The MapEditor.cs script should looks like this:

Next, we’ll need to declare an array for prefabs that are to be loaded and used as tiles. There’ll also be a seletedPrefab game object to store the selected prefab reference and then there’ll a game object list to store all the instantiated game objects.

To be able to add our own components to the Custom Inspector, we’ll need to override the OnInspectorGUI() method. We call the DrawDefaultInspector() method inside it.

Now, we’ll need a few prefabs which are to be loaded and shows in the inspector. First, we create a new folder called “Resources” in the “Assets” folder. Inside it, create a “Prefabs” folder. This is where we’ll put our prefabs.

Get a few sprites that you’d like to use in your game. I used a few from this awesome and free platformer art pack by Kenney.

Drag and drop a few sprites in the scene and add BoxCollider2D component to them. We’ll need the colliders later to detect raycasts. Create prefabs for each of those. Place those prefabs in the “Prefabs” folder we created a bit earlier. Remove the game objects from the scene.


Next, we need to load all the prefabs available in the “Prefabs” folder.

To display the loaded prefabs as buttons in the inspector, we create one button for each loaded prefab. We also get the image used in the prefabs and put it over our button so we know which buttons selects which prefab. The GUILayout.BeginHorizontal () method begins a horizontal control group. All the content inside this will be placed horizontally next to each other. Add the following code inside the OnInspectorGUI() method.

If a button is clicked, the selectedPrefab variable will be supplied with the relevant prefab selected and the focus will move to the Scene View, where we can place/spawn/instantiate our selected prefab.

The inspector should look like this:


See the problem? The buttons are placed horizontally but they continue beyond the width of the inspector. A quick and dirty fix will be counting the number of buttons in a row, and if if goes past a certain number of buttons, end the current horizontal group and start a new one. If you want it to be dynamic, you can check the width of the inspector using Screen.width and set the number of buttons accordingly, like so:

Now, we need to move to the Scene View. Create an OnSceneGUI() method. It handles all the events in the scene view.

In this method, we check if the Key “E” is pressed and instantiate the selected prefab as a game object at the position of the mouse pointer inside the scene view.

The Spawn() method simply takes the mouse position and instantiates the prefab at that position. It also renames the instantiated game object and adds it to the spawnedGO list we created at the beginning and sets the newly created game object as the selectedGameObject. We’ll use this later in the script. Following is the code for the Spawn() method.

At this point, you have your basic tile editor ready to use. Just select the Map Editor game object in the hierarchy, click on a button to select a prefab to spawn, go to the scene view and press ‘E’ anywhere you want to spawn the selected prefab. It’s usable, but we can make it better by adding a few nifty features.


To add an undo feature, we check if the “X” key is pressed. Then, we destroy the last element in the spawnedGO list and remove it from the list too:

We can add a bit of GUI in the scene view itself to indicate if the tile edit mode is active and if a prefab has been selected to spawn.

My favorite feature is the snapped spawning, where the game objects are spawned next to each other so you don’t need to adjust their positions every time you spawn one.

The following code checks for a directional key press (W,S,A,D; not the arrow keys. You can use them too though) and spawns the selected game object next to the last spawned game object. The code checks for the width and height of both the spawned and to be spawned game objects so they are placed right next to each other even if they are of different widths and heights. Note that selectedPrefab is the prefab selected using the buttons in the inspector while the selectedGameObject is the last spawned game object in the scene.

But what if we want to spawn a prefab next to a different game object as opposed to the last spawned one? To achieve this, we can shoot a ray below the mouse pointer in the scene view every time we press the key, say, “R”, and check for a game object at that point. If a game object is found, we set it as the selected game object, so the next time we try snapped spawning, the game object is spawned to the newly selected one. Note that the raycast won’t work if your game object doesn’t have a collider.

To indicate which game object is currently selected, we add a handle at its position using the following code. This will show an “X” mark over the currently selected game object in the Scene View.

You can also add a small circle handle below the mouse pointer to see what the current spawn position is. At the end of the OnSceneGUI() method, call the SceneView.RepaintAll() method to update the scene view.

That should do it. Here’s a glorious .gif.


Click To Download Full Source Code


Harshit Dubey | Unity Game Developer

I am Unity game developer and a casual gamer. I am fond of story-driven games and creating one based on strong and compelling narrative structure is my dream.


Harshit Dubey Unity Game Developer

I am Unity game developer and a casual gamer. I am fond of story-driven games and creating one based on strong and compelling narrative structure is my dream.

Comments are closed.