FWD Level Design – Unity 3D Custom Level Editor Tool

What is this tool?

Custom Unity3D Automated Level Editor and Generation Process

In this blog, I will be going over a tool that I made that turned a roughly 2 and ½ hour process into a 1-hour process, how and why I created it, some of the issues I came across, and some final thoughts. To begin with, though, let me give you a brief description of the tool I created…

I have managed to remove the need to painstakingly scale and place individual objects in order to create levels. I did this by creating classes that: use an image to instantiate 3D objects and generate optimised mesh, create and save navmesh data and scenes automatically, and set up my back-end level selection. (Seen right)


What is FWD?

You’re probably reading this and thinking, “okay that’s a pretty cool tool you got there magic man, but what the h*ll is FWD?”

FWD – short for ‘forward’ – is a mobile game that was made for a university brief at SAE Institute, Brisbane, in 6 weeks; by one person. I have seen potential in the game for a polished portfolio piece, a commercially viable product, and I am actively working on its completion.

To the right is the (rushed and placeholder) gameplay trailer that should give you a good enough grasp of the concept. I am aiming to have the product commercially available on android by the end of January 2022, with future updates already planned.

Anyway, enough about the game and let’s get back to why you’re actually here…


How did the tool come about? First Iteration

Unity3D tedious scaling and repositioning.

To begin with, I was creating my levels by spawning in default cubes, scaling them, and positioning them – manually. For anyone who has used Unity 3D before, you will be able to empathise with me when I say that this was an extremely tedious process of repetitive tweaking.

As a response to this, I knew I had to make something that would speed up my process, significantly. In retrospect, I could have used Unity’s Pro-Builder Tool to rapidly create my levels, however, there are some very specific requirements that need to be met for my use case – we’ll get into these later.

This Segways into the first iteration of my custom level editor which was far from perfect, however, was a step in the correct direction.

Unity 3D custom level editor tool first iteration

This iteration of the tool required me to have a class called WallBuilder attached to an object. This class had a custom inspector with buttons that allowed me to instantiate a cube in the forward, left, right, and backward directions. In addition to this, I included an offset and count variable that allowed me to easily create a specific array of blocks – which I used to create the map boundaries.

These functions were also mapped to the Numpad so I could easily press short keys (8, 4, 6, 2) for a more intuitive interface. I also had an undo and clear button, which would simply either remove the last instantiated cube from the list or clear the entire list.

And now you’re saying, “that’s cool and all, but what’s wrong with it?”

Well, here’s the source code – download it, give it a whirl, and tell me what you notice… Can’t be bothered? Don’t blame you, I’ll just tell you in list form to save both of us time. I’m sure there is a number of smaller things that were also a problem, however, these were the main issues that frustrated me.

  • The walls instantiation direction (8, 4, 6, 2) is in global space.
    • This means scene camera positioning can cause user confusion, increasing cognitive load.
  • Walls can spawn inside of each other.
    • This increases rendering overhead and causes z-fighting.
  • The wall instance reference was not persistent.
    • This meant that duplicating the WallBuilder object or reloading the scene would cause any new additions to start at the object’s origin.
  • You could not use CTRL+Z to undo a change.
    • So you better hope you don’t accidentally press the clear button (I did).

While this list of issues may not seem all that bad in the grand scheme of things, there is one flaw in this process that a few of you keen developers may have already spotted. Each instantiated cube has its own instance of a transform, collider, mesh renderer, mesh filter, and wall component. Now multiply that by about 100-300 to make up just the walls of the level and you’ve got yourself a huge overhead of unnecessary processing

CPU Usage with old system

The most obvious process that I would like to bring to your attention, is the rendering. Each wall has 6 faces (12 tris) that are being rendered, with 1-3 of them never being seen by the player.

These extra faces are using an unnecessary amount of the device CPU. Now, on a computer, this may not be that big of a deal, however, on a lower-end mobile device, it’s the difference between 30 and 2 fps. The provided screenshot of Unity’s profiler shows how drastic this is.

Without reference, this may not mean much to you, however, let’s just say I managed to get more than a 65% increase in CPU performance with my newer tool – we’ll do a comparison when we get to the final iteration…


Like a two-faced friend, we need to cut them out. Second Iteration

Minecraft rendering

Have you ever gone into spectator mode in Minecraft and flew around under the world? Or what about accidentally falling through the world in literally any game ever made?

If you have, one thing you would have noticed is that the objects are completely transparent on the other side. This is to address the exact issue that I was experiencing here. SAVE. CPU. PERFORMANCE.

With this in mind, I have taken a page out of game development 101 and changed the way I was building the levels. (Image source)

So how do we make levels more efficiently and mobile friendly?

Firstly, I took a step back and did a little research into different level editing processes. One video that I found by Brakeys (surprise), featured a ‘Colour to Prefab’ system. Simply put, the code would read an image and instantiate an object based on the colour of the pixel it read. I thought this was brilliant and as my levels are on the same Y axis, I could simply layout the level in an image editing software from a birds-eye perspective and generate it in Unity.

Image for level editing

This is a much more efficient process as being able to draw the level is easier than trying to place objects in 3D space. Not only that, but because it’s using colour to instantiate objects, I can create levels on the fly without Unity. (Anyone have a spare laptop they’d like to donate?)

So, all I have to do is create a handful of wall mesh objects in Blender that only renders specific faces. Then I create a look-up dictionary of sorts to specify a colour that is associated with the correct orientation of the optimised wall.

Great! Problem solved right? – Not quite…

While, yes there are fewer faces being rendered, there still remains the extra overhead provided by individual transforms, colliders etc… Not only that, but it requires an excessive cognitive load to remember what colour is associated with what orientation, greatly slowing down the level creation process. Thankfully, there is always a better way and I looked to the internet to understand how mesh generation works in Unity.


Array’s, Vector’s, Triangles, mish-mash-mesh generation. Final Iteration

After reading through the Unity Documentation on mesh generation and experimenting with it for a little – I felt out of my depth. As someone who is nearly finished their Bachelor of Games DESIGN – (for me) this was a programming challenge like no other. Thankfully, though, one of the skills we are taught is cognitive outsourcing and that, I am comfortable with.

I hear you, “so you’re saying you didn’t program it from scratch?”

No, of course not – that would be a waste of energy and time, considering there are free examples out there. Not to mention I’m already over my time budget for this week’s development and I haven’t even made a dent in the long list of feature’s that need polishing. Don’t get me wrong though, it’s not like there was a solution that did everything I needed it to do straight out of the box. I still needed to understand what was going on and how it was working in order to implement a consistent and flawless system (okay, small designer rant over).

I found a resource online that was endeavouring to remake Minecraft within Unity. This was accompanied by a YouTube tutorial series that explained everything in a relatively easy to understand way. I specifically used the first two videos to understand how to generate mesh and render only what needed to be rendered.

Instead of writing everything that I did to make it work in detail (I did and it was boring to read), here’s a GIF and a list of things that the new system generates.

  • Reads through two images.
    • One for object position, the other for object rotation.
  • Sets level (chunk) size to the image dimensions.
  • Generates floor mesh.
  • Generates wall mesh where black pixels are present.
  • Renders only the faces that will be seen.
  • Uses the generated mesh as a collider reference.
  • Uses a colour look-up Scriptable Object to instantiate objects.
  • Applies a Level Theme material set to the floor and wall mesh renderers.
  • Bakes the Navmesh for AI.
Level generation

Fantastic! But what’s the difference in performance now?

If you get as excited as I do to compare numbers then I’m sure you’ve been looking forward to seeing the improvement. Now, I’m no software engineer and I’m not exactly sure what number’s I should be going for or what everything actually means, however, there is a clear improvement.  It is also worth noting that I am hyper-focusing on purely the rendering, however, one thing I noticed is that while the level generator script was active in the scene, it would increase the script overhead by about 0.2 – 0.4ms. (The profiler was used on the exact same level layout.)

  • CPU difference: 2.29ms faster
  • Dynamic Batch Triangles difference: 300 less
  • Dynamic Batch Vertices difference: 202 less
  • Static Batch Triangles difference: 2.2k less
  • Static Batch Vertices difference: 53.2k less
Old performance
Old Level Layout
Improved Performance
New Level Generator

Efficiency is the lock and automation is the key. Process Automation

Unity3D Custom Level Editor Window

Now that I have an optimised and efficient level generator, the next logical step is to put it in a package that allows me to set up levels without thinking. I did this simply by creating a Scene Generator script (yes lots of generation) and a custom Unity Editor Window.

Put simply, the Scene Generator creates a new scene, instantiates all of the necessary prefabs, generates the level, saves the scene, and sets up all my Scriptable Objects. I also included the option to create a new Level Theme Scriptable Object directly within this editor window, just for efficiency… That’s all I have to say, you get the point.


Final Thoughts

First of all, if you’re still here, thank you for your time. If you liked what you read, why not check out some of my social media accounts linked below. I plan on being much more active in releasing Game Development content, so if you’re interested in supporting me and following along with my projects, please consider subscribing and following.

I have learnt a lot while working on this tool and while it may not seem like much to some people, it is a massive achievement for me. Completing this with only my toolbag of skills and research capabilities is something I am proud of and spent many hours doing so. With this in mind, I am working on creating a Patreon page where I will be posting my source code for useful tools and smaller prototypes for those who would like to use/ contribute to them. If supporting me is something you would be interested in doing, get in contact with me and I’ll move quicker in setting everything up.

Again, thank you for your time and I hope you’re having/have had a fantastic day!

Leave a comment