Unreal Level Design Tutorial

Ian MacGillivray


Making the castle:

Here we're going to create a simple castle, with a trivial little puzzler inside.

1. The Workroom

2. The Castle

3. The Front Door

Here we'll create a realistically shaped front door for the castle, and give the door a trim so it blends into the wall nicely.

Designing the door

Getting the door in place

The outside of your castle should now look a bit like this:

This looks a bit strange, the textures just 'clash' into one another. We'll put a trim around the outside of the door to prevent this.

Trimming the door

Things should look like this now. As we move on we'll be reusing techniques similar to this, and there'll be less pictures, so be sure you've got this right:

Making a movable mesh of the door

A door's not much use if we can't go through it. Here'll make the door open when players get near and close when its safe to do so. We'll put a sound effect on the door's movement too, to add to the atmosphere.

This is a technique we'll use many times in this tutorial. As this is an excerice in UnrealEd, we'll make our static textures in the editor, rather than the usual method of creating them in an external 3D Modelling Program. In future uses, I'll explain it in less detail, so make sure you've grasped it this time.

Only movers can move. Only static meshes can be movers. We're going to take a normal added brush and convert it into a mover.

Animating the door

Here's how the door should look when it's fully open:

5. The Entrance Hall

In this section, we're going to make a small, enclosed entrance hall leading off into the main bulk of the castle.

Making the shell

Adding some archways

There's a couple of cleverer ways to do this that involve moving and intersecting some brushes we have already - but I'll outline one that can't go wrong, feel free to save time if you're feeling clever though:

Things should now look something like this:

6. The Fire

To lend a bit of atmosphere to our castle, and give the player a treat when they come in from the cold terrain outside, we're going to put a cosy fire in the entrance hall.

Setting up the fireplace

Rather than working from scratch, we're going to cheat here and use some premade meshes for the fireplace - kindly provided free from PlanetUnreal.

  • Select FireLogs in the Static Mesh Browser. Right click on the floor below the fireplace and add mesh.
  • Go to the properties of the new mesh and:
    • Display -> Skins: Add (thrice)
    • Set the first skin (Skin [0]) to FireLogHolder - this is the bit holding up the logs.
    • Set the second skin (Skin [1]) to FireLog - this is for the body of the logs.
    • Set the third skin (Skin [2]) to FireLogCap - this is for the end of the logs.
    • Display -> DrawScale: 2.0
  • In front view align the bottom of the fireplace and the bottom of the logs, with the top of the floor. In top view align the fireplace and the logs centrally against the back wall of the entrance hall.
  • I then found the logs seemed to stick out a little further than they should, despite our previous scaling on the Y axis for the fireplace (any more than 1.5 made the mesh look odd. Try moving the fireplace out a little in 3D view, until you have a good compromise between the fireplace not resting against the wall, and the logs not sticking out too far

    Hopefully you'll end up with something that looks like this:

    Animating the fireplace

    Now we've got a fireplace, it's time to add some fire - and a bit more sound to add to the atmosphere. We'll be using an emitter to add some smoke and flames, some lighting for the glow of the fire, and attaching some ambient sound to the finished product.

    Smoke:
    Fire:

    You can now pop into preview mode (hit the joystick or press 'P') to see your animations. If you don't like them, try playing with the velocities, the number of particles and the size of the particles, until you're happy with the effects.

    Glow:

    We're going to use two lights to create the 'glow' of the fire. One will give off a subtle pulse of light, the other will have some flickering effect. This Unreal version doesn't deal too well with slow flickering, so we'll make the latter one quite dim so as not to induce seizures.

    As usual, here's a picture of what you should be expecting to see by now:

    Sound:

    We could add the fire's sound on any of the objects we've created, or even place a dedicated AmbientSound actor. I'll talk you through placing it on one of the meshes, but the procedure's pretty similar for adding it anywhere else.

    7. The Grates

    In order to have a little bit of player interaction in moving about the map, we'll fence them off from the bulk of the castle with some grates they need to open. Opening the grates will set off an alarm, which they'll need to then go and turn off.

    Making the wall

    Here's how your edges should look after the scaling and panning:

    Making a hole

    We're going to make a mover again - I hope you remember this, here goes:

    Making a door in the grate

    That's one side done - now either follow all the above again for the other side (not recommended) or duplicate all your brushes and move them along. Be sure to re-set up your mover's keyframes (else it will fall diagonally) and to name your new mover 'RightCircle' (or 'LeftCircle' if you started on the Left).

    8. The Steppers

    In order to control our little adventure in the castle, we'll use the tried and true paradigm of having a block of wood to step on, which sets of all sorts of fun. We'll just make the steppers now, and leave the logic for later.

  • And we're done. Duplicate this (remembering to change the BumpEvent) all over to the other room now - or follow the steps again. Here's what it looks like:

    9. The Ball Holder

    Part of our scene will involve setting off a trigger to quell an alarm - and when this happens, a ball will be thrown from the ceiling and get pulled into a slightly futuristic little ball holder.

    Making the shell

    • Make a cube, dimensions 128 136 256. (the odd dimensions are to fit the ball)
    • In top view align it towards the back of the castle and with its side touching the left side wall. In front view have the bottom of this cube touch the floor.
    • Pick texture: StuddedTrim. Add the brush.
    • Select all surfaces, Align -> Planar.

    Cutting the insides

    We're going to do some fairly elaborate cutting here. An acceptable job could be done in a much simpler fashion, but we're not going to be pushing the engine's performance even with the extra polygons we'll be using, and we'll end up with quite a nice effect.

    • Make a tetrahedon radius 64, extrapolation 3
    • In all views place it inside the new box, with one side touching the side walls. It should fit *exactly* so go down to 1 unit to place it.
    • Pick texture: glassnoopacity. Subtract the brush.
    • Move your active brush 8 units to the right (away from the side wall). Intersect (we may as well save polygons where we can) and subtract again. See below for what you'll end up with if you're confused.
    • Repeat the above step until there's nothing to be subtracted by the brush.
    • In 3D view, put a light right back in the middle of the box - I went for a fairly standard white light with LT_Type: LTSubtlePulse.

    We're done, here's what you're after - preview it in dynamic mode or lighting mode to see the light effect if you have one.

    10. The Ball Thrower

    This is going to be a shaft coming out of the ceiling, which our ball will supposedly travel down before being flung across the screen.

    • Make a cube, dimensions 128 136 256.
    • In all views place the brush directly over the Ball Holder, then Intersect.
    • In top view rotate the brush 180* (making sure it's still perfectly in line with the Ball Holder afterwards) and drag this to the opposite wall. In front view drag it up so it's roughly level with the bottom of one of the stained glass windows. In top view again, take it to be 192 units from the side wall.
    • Check, really check, the brush and the ball holder are perfectly in line along the x axis (the 'width' of the castle). There'll be a very nasty surprise later if not. Add the brush when you're sure.
    • Take the active brush, and move it somewhere away from everything else. Add
    • In front view, rotate the brush 45* so it's facing down and towards the first ballholder we made.
    • Drag the active brush so its lowermost corner touches the bottom right corner of the newly added cube. You might need to toggle grid snapping off for this. Be prescise.
    • Deintersect. Feel free to delete the brush you added in the middle of the room now.
    • Take your newly made brush, line up its lowermost corner with the bottom right corner of the shaft perfectly, and deintersect (so it doesn't add through the side wall). Add the brush.
    • Make a cube, dimensions 128 136 256.
    • In front view rotate the active brush 90*.
    • Line up the active brush's right hand side up with the right hand side of the brush you just added, and its bottom with the bottom of the brush you just added. Add the brush.
    • Count the number of units between the ceiling, and the top of the brush you just made. You can do this fairly easily by turning the unit count down to something like 16 and counting the number of 'large squares' (8 small squares in size) - and multiplying at the end (4 large squares = 4x8x16 = 512 units, for example).
    • Make a cube, height: 128, width: 136 and breadth: the number you just got.
    • In front view line the active brush up between the ceiling and your most recent brush (it should fit perfectly, for obvious reasons). Add the brush.
    • Select all the brushes you've made your shaft up with, and then move them about 64 paces back towards the centre of the room. Texture them with StuddedTrim, align planar and scale U: 1.0 V: 1.5.

    Here's how the whole thing should look in front view when you're done:

    And here it is textured up and in context:

    11. The Ball

    This large glass ball will be thrown around our screen, but the karma physics engine (and all the hassle of variances when running the level) are beyond the scope of this project. We're going to make an elaborate mover instead, which nicely conforms to the laws of physics.

    Making the ball

    • Make a tetrahedon radius 64, extrapolation 3
    • Pick texture: glassnoopacity. Put the brush somewhere out of the way inside the back room of the castle and add.
    • Select all surfaces, Align -> Planar and scale 5.
    • As usual; convert to mesh, delete the brush, select the mesh, add a mover.

    Animating the ball

    Get a cup of tea, this might take a while...

    • Take your ball, and move it so it's perfectly in the mouth of the new shaft you've created. I find it easiest to do the bulk of the movement in the 3D view, where movement can be limited to just one axis - and tidy up in the Top/Front/Side views.
    • In 3D View place the ball as far back into the horizontal part of the shaft as you can, without it poking out through the back as shown:

    Now for the movement. Annoyingly, most Unreal editors will move your ball back to Key frame 0 every time you go to a frame which hasn't yet been set. If you can't find a workaround for this in your editor (and I can't), I suggest using the active brush to note where you ball was last, and keeping a running note of how many rotations its undergone on paper/notepad.

    • Set Key 0.
    • Set Key 1.
    • Move the ball only along the X axis, so it's just out of the shaft. In front view, rotate the ball 180* anti clockwise (as though it were rolling out of the shaft) - as below:
    • Set Key 2.
    • Move the ball 256 units more along the X axis. In front view, rotate 180* anti clockwise again. Move the ball 128 units 'down' along the Z axis.
    • Set Key 3.
    • Move the ball 192 units more along the X axis. In front view, rotate 180* anti clockwise again. Move the ball 192 units 'down' along the Z axis.
    • Set Key 4.
    • Move the ball 128 units more along the X axis. In front view, rotate 180* anti clockwise again. Move the ball 256 units 'down' along the Z axis.
    • Set Key 5.
    • Move the ball 128 units more along the X axis. In front view, rotate 180* anti clockwise again. Move the ball so its bottom is touching the floor. It would be nice to 'squash' the ball at this time, but that's a bit too advanced for a basic unreal mover.
    • Set Key 6.
    • Move the ball 96 units more along the X axis. In front view, rotate 90* anti clockwise. Move the ball 'up' 64 units along the Z axis.
    • Set Key 7.
    • Move the ball 32 units more along the X axis. In front view, rotate 90* anti clockwise.
    • Set Key 8. You'll notice you can't do this through the right click menu - instead select the Mover Actor Properties and go to Mover -> KeyNum. While you're here, change NumKeys to 10. We'll only have 9 keys, but the mover will act on display numkeys-1 when we get past 7 keys.
    • Move the ball 96 units more along the X axis. In front view, rotate 90* anti clockwise. Move the ball back down to the floor.
    • Set Key 9 as above.
    • Place the ball directly against the side wall and right inside the ball holder (make sure it lines up). In front view, rotate 90* anti clockwise. This extra distance and rotation will make the ballholder seem to pull the ball in as the ball reaches its entrance.

    Stop, breathe, and then check all of your frames are where you want them. You should see the ball tracing a nice curve towards the ground, bouncing, and then accelerating into the ball holder. Run my completed level to see the animation. The ball never moves on the Y axis.

    • Now for some final tidying up. Open the Properties window for the mover and:
      • Mover -> MoverEncroachType: IgnoreWhenEncroach - don't let anything get in the way of the animation.
      • Mover -> MoveGlideType: MV_MoveByTime - we want linear movement (actually we'd like acceleration, and could achieve it with even more laborious keyframing, but linear will do).
      • Mover -> MoveTime: 0.4 - speed is an issue with this many frames.
      • Object -> InitialState: TriggerToggle. - again, a clever trigger will mean this only gets toggled once.
      • Events -> Tag: MovingBall.

    12. The Steps

    We're going to create a simple climbing set of stepping blocks, much as you see in a children's playground. The last one will sink as a player stands on it, silencing the alarm.

    Making the steps

    • Pick Texture StuddedTrim.
    • Make a cylinder, height: 32, outer radius: 16, sides: 24
    • In top view move the active brush so it's 192 units from the back of the entrance hall wall, and 192 pixels left of the centre of the room. In front view align its bottom with the bottom of the floor. Add the brush. Add the brush.
    • Make another cylinder, this time with a height of 64.
    • In top view, move the brush so it's 64 units to the right of the last one. In front view align its bottom with the bottom of the floor. Add the brush.
    • Make another cylinder, this time with a height of 96.
    • In top view, move the brush so it's 64 units to the right of the last one. In front view align its bottom with the bottom of the floor. Add the brush.
    • Make another cylinder, this time with a height of 128.
    • In top view, move the brush so it's 64 units to the right of the last one. In front view align its bottom with the bottom of the floor. Add the brush.
    • Make another cylinder, this time with a height of 160.
    • In top view, move the brush so it's 64 units below the last one. In front view align its bottom with the bottom of the floor. Add the brush.
    • Make another cylinder, this time with a height of 192.
    • In top view, move the brush so it's 64 units below the last one. In front view align its bottom with the bottom of the floor. Add the brush.
    • For all the cylinders (at once is fine):
      • Select all sides -> Align: Face
      • Select the top faces -> Align: Planar Floor. Individually select cylinder tops and pan a bit if you don't like the texture on the top of any.

    Animating the falling step

    We're going to work with the last cylinder - we'll want this one to fall. Once it's fallen, the alarm will be turned off. As usual, we'll need it as a static mesh to make it a mover:

    • Select the tallest cylinder. Convert to mesh, delete, select the mesh, add mover and finally put the mover back where the cylinder was.
    • Set Key 0, Set Key 1, move the mover 128 units down (it going through the floor is fine, it'll just end up underground).
    • And finally:
      • Object -> InitialState: TriggerToggle.
      • Mover -> MoverEncroachType: IgnoreWhenEncroach.
      • MoverEvents -> ClosedEvent: AlarmOff

    13. Tinted Windows

    Just one more thing before we start setting up all of our triggers, our alarm system et cetera. Let's put some nicely tinted windows on one of the wall. Unfortunately, Unreal doesn't allow for colour-tinted lighting to shine through (though if you have time, you can fake it with an extremely elaborate set of point lights), but we'll still give the windows a bit of a glow and let some of outside's light in through them.

    • Make a cube, dimensions 256 16 64
    • In front view place this cube within the bottom perimiter of the castle walls, and about halfway along the wall of one of the side rooms.
    • Subtract the brush
    • Select all the surfaces you've just revealed, and Pick Texture: WallTrimStone
    • Make a sheet, height: 256, width: 64, align: Y-Axis. It should be aligned directly in the middle of your subtracted brush - if not, move it there.
    • Add a special brush with the following options ticked; semisolid, two sided.
    • Select the sheet, Pick Texture: glassnoopacity, and scale the texture to 0.3.
    • Finally, in Properties, select Display > AmbientGlow: 128 - (to help with the glassy effect).

    Do the same on the other side, or duplicate the brushes (as always, being sure the subtracted brush comes first, if you're not duplicating them all at once. To make the look entirely different, simpy U-Pan the texture a bit (-64 and some tidying worked for me.)

    14. The Alarm System

    We're done with physical objects in the castle now, it's time to put the logic of the puzzler in. We'll start with an alarm system - a flashing red light and a siren should do the trick.

    Making the light

    • In the Actor Class browser go fetch an Actor -> Light -> Triggerlight. Add it by right clicking on the wall of the entrance hall you can see from the back end of the castle (next to the steppers).
    • In Properties -> LightColor pick a mid-bright red. I ended up with values of Brightness 203, Hue 253 and Saturation 145.
    • In the same window, you'll also need to set:
      • Lighting -> bDynamicLight: True - Due to a bug in the editor, this won't be on by default, but a triggerlight won't work without it.
      • Lighting -> LightType: LT_Pulse. A light effect would be nice too, but these are very tempermental and prone to breaking. Put one in if you want, but look here first if your game starts doing strange things. I recommend LE_Shock or LE_Rotor.
      • Object -> InitialState: TriggerToggle.
      • TriggerLight -> bInitiallyOn: False (this may be the default in your editor, but check).
      • Events -> Tag: RedLight.

    That's it for now, the siren will be added along with the triggers below.

    15. Triggers

    Ok, now it's time to put it all together with some triggers before we add in some more lighting and are finished.

    The Door

    If you recall, we want the door to stay open whenever the player's near it - we don't want it to simply close on them, that's not nice. We'll use an intricate set of 5 trigger controls, and the door will remain open whenever a player is within their combined radius in order to achieve this. Using just one control would result in too large a radius (there's no way to be more specific) and would allow the door to be opened from the side rooms.

    • In the Actor Class browser select Actor -> Triggers -> Trigger.
    • In 3D View go outside the castle, and right click on the doortrim to add this trigger. Move it so it's in the centre of the door on all axis.

    • Go to the trigger properties and set:
      • Events -> Event: Door.
      • Collision -> CollisionHeight -> 256
      • Collision -> CollisionRadius -> 190 - this is just enough so that it can't be triggered from the side rooms - to see for yourself, right click the head of 'top view' and select Actors -> Radii view.
    • Create two identical new triggers, and in top view move the new triggers 256 units above and below the current trigger, then in front viewensure they're lined up properly (so the bottom of their radius touches the floor).
    • Finally, create two more triggers as above, but this time with a collisionRadius of 250. In top view, move these below and to the left/right of the lower trigger.

    Here's what your door trigger system should end up looking like (in top view). It's elaborate, but beautifully functional:

    You'll note I actually added another trigger, and moved the top three around, to ensure the small gaps down the sides of the entrance hall didn't cause any problems...it's a minimal risk, but feel free to do the same if you like.

    The Alarm System

    We're going to set up a script to run our alarm system, it'll wait for the alarm to be set off and then play the siren and lights continually until the alarm's turned off, and finally it'll throw the ball down into the ball holder. The AlarmOn signal will come from triggers on the top of the steppers - we could avoid these extra triggers by assigning the AlarmOn event to moverevents on the doors that leadthrough the grates, but moverevents are a bit tempermental at times.

    • Create a trigger, and place it directly on top of one of the steppers.
    • Set Events -> AlarmOn
    • Do the same on the other stepper.

    Note that from now on, whenever you build you'll get a message warning you that no actor has a tag matching the event 'AlarmOn'. That's fine, it's just a bug in the editor - it doesn't check ScriptedTriggers.

    • In the Actor Class Browser, go to Actor -> KeyPoint -> AIScript -> ScriptedSequence -> ScriptedTrigger. In 3D View add one of these in the main room, on the back of the entrance hall wall, about halfway up the wall.
    • In the Properties of the new ScriptedTrigger, set Sounds -> AmbientSound: Siren (find it in the Sound Browser and click 'use'). Leave volume at 0.
    • Now, go to AIScript -> Actions, it's here we'll create our scripted sequence. Click 'Add' to make an action, here's what you want, in order:
      1. ACTION_WaitForEvent. ExternalEvent: AlarmOn.
      2. ACTION_TriggerEvent. Event: RedLight
      3. ACTION_PlayAmbientSound. AmbientSound: Siren (as above). SoundVolume: 128.
      4. ACTION_WaitForEvent: ExternalEvent: AlarmOff
      5. ACTION_PlayAmbientSound. AmbientSound: Siren (as above). SoundVolume: 0. - this is the canonical way to deal with this.
      6. ACTION_TriggerEvent. Event: RedLight
      7. ACTION_TriggerEvent. Event: MovingBall.
      8. ACTION_DestroyActor. Tag: ScriptedTrigger - The script actor self destructs, and we regain its resources.

    16. Finally...

    You're probably eager to play the level by now. Assuming you haven't done so already, add a bunch of lights (I like to have lots of low intensity lights dotted around near the top, not too near to any walls or ceilings, to provide a nice ambient light from above). Pop down a player start point and enjoy!