November 19, 2014 by jonmillymiles
My foray into Blueprints has led me down an involving and complex route and taken me off to the side for about a week. It was only this morning that I realised that not only was the work I was doing not going to help, it would pretty much put an end to the design that I created at the start of this module.
These are the level plans for the first area of the game. They feature areas where modular construction principles can be used to good effect – lots of similar rooms and a layout that should be easily recreated using a grid.
The maps are deliberately large, however if you look closely they also feature large areas where common elements can be found. So for example transit accommodation, used for short stays, will feature identical furniture in each room: the arrangement and styling may vary, but the objects within will mainly be the same. Therefore a simple room can be created with a script which will place items in a semi-random fashion.
What I have been doing is experimenting with the construction scripts within the Blueprint framework to try to find out just how much I could build with them, and just how far I could take the randomness.
There is a really useful pair of video tutorials that explain how you can create dynamic material instances within a construction script in order to give a material a random colour. Here they are:
Taking these as a basis I was able to start randomizing some of the properties of my bed mesh. This allowed me to generate separate patterns for both the cover and the pillow case but allowed me to keep the colour unique. However, I didn’t want to place three separate objects (frame, mattress and pillow) I wanted to find out how to include it in a single mesh. To do this I saw a feature of UE4 where you could assign several materials to a mesh in the video below. However this is for Blender and not 3DS Max, but the principle is exactly the same: just assign materials to faces or objects and then import them into UE4. A word of warning though, if you create a complex object generated from multiple meshes in 3DS it is advisable to tick the “Create single mesh” or you will end up with several meshes each with a single texture.
So, I had randomization worked out, and as a by-product multiple materials on a single mesh.
As a lot of my level consists of rectangular rooms I wanted a construction script that would do this for me. To achieve this I had to create meshes within a blueprint.
I began by investigating the Custom Examples level that was mentioned in my Blueprints of Life post and found out that to spawn a mesh is easy within a blueprint – you just need two nodes: Add Static Mesh Component and Set Static Mesh as per the picture below:
This really simple principle forms the basis of constructing rooms in UE4, you just need to change the New Mesh value to the mesh that you would like for the new static mesh – if this value is wrong, or the targets are not connected then the mesh will not draw.
All we need to do now is to generate a lot of them!
I started with the floor as it is a relatively simple task. The basis involves two For loops one for the X axis and another for the Y axis, these are used to generate the coordinates for the new mesh that is added. This is then applies to the orange Relative Transform input on the first node. Heres the principle of the logic:
The coordinates are generated for the new mesh by multiplying the index of the For loops by the X and Y size of the mesh. As my floor tiles are conveniently square it is an even 200 units for each tile in both the X and Y axis.
So the first tile is at X: 200 x 0, Y: 200 x 0
The second is at X: 200 x 0, Y: 200 x 1
And so on as per the pattern above.
Here’s the Blueprint:
This is then made easier by making the last index for the For loops X and Y variables, which are then made public so that they can be manipulated from the editor. The same system was used for the ceiling, with additional code to add lighting at various X and Y frequencies.
The walls were also constructed initially in a similar fashion to the floor to generate a single plain. This was then duplicated within the loop including an offset to generate the opposite side of the room. This was then duplicated again in order to create the remaining two walls. This left me with a problem… how do you get into the room???
Allow me to digress a second…
I have recently downloaded an app on my phone called Pixel Dungeon which is a game that generates its levels randomly using a procedural methodology. No two games are ever the same, but the concept of randomly generated levels has been with me since I played Captive (Antony Crowther, Mindscape) in 1990. This game generated all of its levels using a random level generator so that the game would effectively last forever. My dad played it for over two years and got to level 114 ish. Each “level” consisted of 11 bases that had to be destroyed and each took an experience player about two hours to complete at the least. So you can roughly see how much time he sank into the game.
But this principle has stuck with me. So I thought about my lack of doors and wondered if I could get them to be produced randomly… well I did it. The code isn’t pretty and I’m not going to explain it. It could be optimised but it serves its purpose at present. Here it the code for just the walls including a random door element on the ground level.
For those who do not understand the colours:
- Blue – References to meshes
- Red – Boolean values (True/False)
- Cyan – Integer values (Whole numbers)
- Green – Floating point values (real numbers like 3.14159265359 <- That’s why I’m fat… I love pi!!!)
- White – Process Flow
So why was this me being sidetracked? Well my maps are clearly planned, thus they are not random. Therefore this has been an exercise in fun and challenge rather than a meaningful output. So I added a couple of variables that would allow me to make more use of it as a corridor making feature for the game.
And here’s a video of it in action and a demonstration of how it can be used to rapidly generate content.