For as long as we have been playing video games, there has been one particular genre that has stayed with us almost from the beginning, the platformer. Starting with Donkey Kong with the familiar content that we know, refined in Super Mario Brothers, given more action with Mega Man, sped up with Sonic the Hedgehog, and used even today with games such as Braid, Super Meat Boy, and They Bleed Pixels. There is something that draws us to this specific type of game, especially within the indie game community.
With that in mind, I thought a fitting first project would be to recreate this beloved type of game and prove that UDK is definitely not just for creating first-person shooters.
We will be creating a side-scrolling platformer game using the three-dimensional engine to do two-dimensional gameplay. In this project, the player can move left and right, jump on static and moving platforms, and collect coins/collectables, some of which may modify the player's behavior.
We will first approach the project using nothing but Kismet and the UDK Editor. This particular project will be explained with much greater depth than the other projects in order to jog the memory of anyone who has not used UDK in a while and may come up to speed while completing this project.
For those who need a quick reminder, Kismet is a system of visual scripting in UDK that makes it possible for people to affect the game world and design gameplay events. For teams without a programmer, Kismet can be a godsend. It makes it possible for someone without any coding knowledge to do things that would otherwise require the use of UnrealScript, the programming language that the Unreal engine uses.
In future projects however, I will assume a familiarity with the things I have taught in this project.
Once we finish this project, we will have a good understanding of how UDK can be used to create games that it wouldn't necessarily be considered for at first glance; having a three-dimensional engine, we will create a game with two-dimensional gameplay. Also, we will be able to create our very own side-scrolling platformer game in the same vein as Mario. We will also learn about some of the assets available in UDK by creating subsequences and prefab objects, which we can apply to future projects.
This project will be split into five tasks. As we are not creating any enemies in our game, we do not have to deal with UnrealScript in this project. It will be a simple systematic process from the beginning to the end. Here is an outline of our tasks:
Level and camera creation
Adding player functionality
Adding collectables/power ups
Designing the level layout and background
Before we start, let's make sure that we have the latest version of UDK (February 2012 as of this writing), which can be downloaded from http://www.unrealengine.com/udk/downloads/.
Apart from that, all of the assets used in this project should already be included within the base UDK installation.
This project and all projects assume that the user has used UDK to some extent in the past and is familiar with the concepts of building brushes as well as navigating around the game environment. The user should also have familiarity with Matinee and know how to do things such as adding keyframes.
That being said, I will do my best to be as descriptive as possible in how to do things.
Before we start working on the project, we must first create a new map. To do this, we must first select File | New Level... and from the pop up that comes up, select one of the top four options (I selected Night Lighting, but it doesn't matter which one you choose).
There are many different options that you can use in determining how UDK is displayed and whether it works for you. I encourage you to take some time to figure out what you like and don't like. While having a Front viewport may be nice, I like having a larger screen space for the Perspective view so that I have a better idea what the area I'm creating looks like. This is more my personal preference than anything but it is what I will be using from here on out.
If you wish to follow me, select View | Viewport Configuration | 1x2 Split from the top menu so that your screen looks like the following screenshot:
Now that we have a base level to work in, let's start building our game!
Bring up the World Properties menu by selecting View | World Properties from the menu bar at the top of the UDK interface. Type
Game Typein the search bar at the top of the World Properties menu to bring up the Game Type menu and the relevant options for us. From there, change the drop-down menus for both Default Game Type and Game Type for PIE to UTDeathmatch. As we are in the Zone Info section, under Kill Z set the value to
Now let's make sure our player spawns in the correct position. Select the PlayerStart_0 object and press F4 to access the object's Properties window. From there, in the search bar at the top, type
Location. Once you find the Location vector variable, set the X value to
0. Next, type
Rotation. Make sure that the Roll and Pitch options are set to
0and change the Yaw option to
Also, note the numbers listed on the Y and Z values in the Location variable, as we will be using them in a future step.
A vector in Unreal is a variable (a struct, specifically) that contains three floating point numbers inside it: X, Y, and Z. Conceptually, it corresponds to a three-dimensional Euclidean vector often used in linear algebra; in the previous instance it is used as the position of our PlayerStart_0 object in three-dimensional space.
From here we need to access the Actors Classes panel by selecting View | Browser Windows | Actor Classes. Inside, click on the CameraActor selection that is located under Categories | Common | CameraActor.
Go back to the editor menu, right-click, and select Add CameraActor Here. With the object placed, press F4 to go to the object's Properties menu. Change the value of X in the Location property to be
-650, and the Y and Z values to the same position as PlayerStart_0,
With the necessary objects in place, we open up the Kismet interface by clicking on the K icon at the top of the UDK interface on the main toolbar. From there we first need to create a Player Spawned event. We then right-click anywhere inside the large area in the upper portion of the interface. Choose to create a Player Spawned event by choosing New Event | Player | Player Spawned from the menu that pops up. Click on the Player Spawned event's Sequence Event to have the Properties window come up and change the value of Max Trigger Count from
Underneath the Player Spawned event, right-click under the Instigator output and select Create New Object Variable. You should see a line connecting the output to the new object variable. If not, click on the connector (the purple triangle) and drag until you select the new variable we created and let go. Click on the new object to open its properties in the bottom-left panel of the Kismet window. Under Sequence Variable, we change the value of Var Name to
In all the instances where we are using the named variable Player, we could use the actual Player variable by right-clicking anywhere inside the large area in the upper portion of the interface and selecting New Variable | Player | Player and unchecking the All Players option in the Properties window, but a review of how named variables can be used can be quite useful for things we will be doing in later projects.
To the right of the Player Spawned event, create a Set Camera Target action by right-clicking and selecting New Action | Camera | Set Camera Target. Right-click under the Target input and select New Variable | Named Variable. Click on the variable to open its properties. In Properties under Find Var Name, type in
Playerand press Enter. You should see the red X change into a green checkmark. Connect the Player named variable that we created to the Target input.
Exit Kismet, click on the CameraActor_0 actor, and return to Kismet by clicking on the K icon on the main toolbar. Right-click on the Cam Target input (the pink square) and select New Object Var With CameraActor_0. Finally, connect the Out output from the Player Spawned event to the In input from the Set Camera Target action we created.
If we started the game at this point, we would notice that when the player spawns we can see the player from a third-person perspective that looks great as long as we do not move. You will notice that the camera does not move with the player and if we move our mouse, our player will turn around and allow us to move in ways that are counter-intuitive to what we are trying to create. Let's fix those issues now.
Create an Attach to Actor action by right-clicking and selecting New Action | Actor | Attach to Actor. Connect the Target input to the Player variable, and Attachment to the CameraActor_0 variable that we created in the previous section. In the properties for the Attach to Actor action, check the Hard Attach option and connect the Out output from the Set Camera Target action to the In input of the Attach to Actor action.
Create a Toggle Input action to the right of the Attach to Actor action by right-clicking and selecting New Action | Toggle | Toggle Input. In the action's properties, uncheck the Toggle Movement option and make sure that the Toggle Turning option is checked. Connect the Player named variable to the Target input. Connect the Out output of the Attach to Actor action to the Turn Off input on the Toggle Input action.
You can connect all of the targets to the same player, or create multiple Player named variables to house all of the things; it makes no difference, but one may make your code look more visually appealing.
Save your project (File | Save All) and start your game by pressing F8 or selecting Play | In Editor on the main toolbar.
We have just created a camera that will follow our player in a similar fashion to that used in side-scroller games. More specifically, we have, through Kismet, told our game that we wish to use a different camera instead of the pawn's default one. We have also disabled the ability for players to turn, for the time being, to prevent nonstandard movement.
Now, as amazing as having a camera that follows our player around is, there are still plenty of things that we need to do to get this game to be the best that it can be. For instance, we want the player to move left and right on the screen when we press A and D. We are also going to adjust the player's jump height and remove the ability to double jump (as it is defaulted in UTDeathmatch).
Now, let's get the controls working correctly.
With your current level saved, exit out of UDK and open up Windows Explorer. Go to the folder you installed UDK toâthat is, to the
UDKGame\Configfolder. Right-click on the
DefaultInput.inifile and select Copy. Then use Ctrl + V to paste a copy of the file into your folder.
Always create backups of files before you modify them, just in case. On the same note, other projects will assume you are using the default version of this file, so be sure to change the file back when you are ready to move on.
It is often a good practice to have a separate and clean install of UDK for each project you are working on, which acts as a control so that you always know what was there originally.
Alternatively, you can make use of a version control software, like Perforce to enable you to backtrack your steps, but that's beyond the scope of this book.
.Bindings=(Name="GBA_MoveForward",Command="Axis aBaseY Speed=1.0") .Bindings=(Name="GBA_Backward",Command="Axis aBaseY Speed=-1.0") .Bindings=(Name="GBA_StrafeLeft",Command="Axis aStrafe Speed=-1.0") .Bindings=(Name="GBA_StrafeRight",Command="Axis aStrafe Speed=+1.0")
With the following:
;----------------------------------------------------------------- ; Hotshot - Begin Changes ;----------------------------------------------------------------- .Bindings=(Name="GBA_MoveForward",Command="Jump | Axis aUp Speed=+1.0 AbsoluteAxis=100"); .Bindings=(Name="GBA_StrafeLeft",Command="Axis aBaseY Speed=-1.0") .Bindings=(Name="GBA_StrafeRight",Command="Axis aBaseY Speed=+1.0") ;-----------------------------------------------------------------; Hotshot - End Changes ;-----------------------------------------------------------------
;----------------------------------------------------------------- ; Hotshot - Begin Changes ;----------------------------------------------------------------- .Bindings=(Name="Left",Command="GBA_StrafeLeft") .Bindings=(Name="Right",Command="GBA_StrafeRight") ;----------------------------------------------------------------- ; Hotshot - End Changes ;-----------------------------------------------------------------
Save the file, and start up the UDK Editor once again.
Inside the Properties window type
SetJumpZ 750as the value for Commands. Connect the Player variable to Target. Connect the Out output from the Toggle Input action to the In input of the Console Command action.
Next, create a Modify Property action by right-clicking and choosing New Action | Object Property | Modify Property from the menus. Expand Properties by clicking on the + icon in order to create a new array entry. In the Property Name variable, type
MaxMultiJump. Check the Modify Property option and change the value of Property Value to
0. Connect the Player variable to the Target input. Connect the Out output from the Console Command action to the In input of the Modify Property action.
Create a Toggle Cinematic Mode action by right-clicking beside the Modify Property action and selecting New Action | Toggle | Toggle Cinematic Mode. Uncheck all of the options apart from the Hide HUD option. Connect a Player variable to the Target input, then the Out output from the Modify Property action to the Enable input of the Toggle Cinematic Mode action.
Finally, create a Give Inventory action by right-clicking and selecting New Action | Pawn | Give Inventory. Check the Clear Existing and Force Replace options. Connect a Player variable to the Target input, then connect the Out output from the Toggle Cinematic Mode option to the In input of the Give Inventory action.
Save your project (File | Save All) and start your game by pressing F8 or selecting Play | In Editor on the main toolbar.
With a minimal amount of work, we have accomplished a large amount of what is needed in order to create our side-scrolling platformer game with a player that is controlled similarly to the games we mentioned at the beginning of the project. The player can now move appropriately, and can only jump once. We have removed the player's weapon, and removed the default HUD, and are well on our way to having an awesome project completed!
To get a clear picture of why/how the changes in our
.ini file were made, I feel it is important for me to describe it in detail. The pawn that we are using uses its rotation in determining where it should move by default when we press W, the up arrow, or forward on an Xbox 360 controller; the player will move by default straight forward just as you press the down arrow or S, or the back arrow/button will move the player backwards. Left and right will either rotate or move the player to the pawn's left or right respectively. Without using UnrealScript to modify the
PlayerController class and/or pawn, we can just change what the actions do.
Thinking in two-dimensional terms, we want to move the pawn forward when we press the right arrow, move him backwards when our player presses the left arrow, and have the player jump when they press the up arrow or jump.
Note that the changes that we made to the
.ini file were just modifying what the actions associated with the buttons were meant to do. If you wanted to replace the names of the bindings to be associated with their new connections, that is also a viable option; however, it would require replacing a lot more than we already have.
Now that we have the camera system and a functioning player, it would be a good time to start adding things that the player can actually travel to. In this section, we will be creating both static and moving platforms.
Open the Content Browser window in View | Browser Windows | Content Browser. Find the following static mesh:
StaticMesh'FoliageDemo.Mesh.S_PavingBlocks_01'. Click on it and return to the editor's screen. Right-click on the ground of your level and add the mesh to your level (you may need to load it in first) by selecting Add Static Mesh: FoliageDemo.Mesh.S_PavingBlocks_01.
Delete the static mesh of the box that is currently in the level by clicking on it and pressing the Delete key. Select our new platform and change its location to
240in the same way that we did in the first step. Duplicate the mesh three times and rotate it to face the three sides the camera can see. You can duplicate the object by either holding down Alt and dragging or by going to Edit | Duplicate. In order to rotate, you can use the translate tool or alter the properties.
Make another duplicate of the top platform by holding Alt and dragging along the y axis (256 units). Right-click on the newly created platform and select Convert | Convert StaticMeshActor To Mover. Inside the Properties window, change the Collision Type to COLLIDE_BlockAll and check Block Rigid Body.
You can check the distance from one point to another by holding down your middle mouse button and dragging to where you want to check. This can be quite helpful in games where the spacing between objects matters, which it does quite a lot in a platformer.
Back in Kismet, create a new subsequence by right-clicking and selecting Create New Sequence : 0 Objs. When the naming dialog comes up, type in
Moving_Platform_LRfor the Sequence Name field and click on OK. Double-click on the sequence in order to enter it.
Create a Level Loaded event by right-clicking and selecting New Event | Level Loaded. To the right of it create a new Matinee sequence by right-clicking and picking New Matinee. Connect the Loaded and Visible output of the Level Loaded event to the Play action of Matinee. In the Matinee's properties under Seq Act Interp, check Looping and Rewind if Already Playing.
Outside the editor, click on the soon-to-be-moving platform and then go back to Kismet, and double-click on the Matinee sequence to enter the Matinee editor. Right-click inside the Group List (the dark-gray column below all the tabs with text and to the left of the timeline. From the context menu that appears, click on Add New Camera Group. When prompted for a name, type in
To create our moving platform, create two keyframes by clicking on the Add Key button at the beginning of the Movement track with the first at the 0:00 spot and the second one at the 1:00 spot. Then create another at the 6:00 spot. These keyframes won't be moving at all, so do not change their positions. Create two more keyframes at the 3:00 and 4:00 spots. At each of these keyframes move our platform along 640 pixels along the y axis. Once the first one is completed, you will have to adjust the second one to the same placement as well. Be sure to make the Location values match exactly.
Specifying a time in which a keyframe should be reached is fairly simple. Click on the keyframe to select it, right-click, and then select Set Time; from there you can change any of the values you may need.
Now that we have a single platform already created, exit out of Matinee and exit this sequence. Copy and paste the sequence. Right-click on the newly created one and rename it to
Moving_Platform_UD. Double-click on the new subsequence and enter its Matinee sequence. In this Matinee, change the 3:00 and 4:00 values to change on the z axis 256 units down.
Make sure that the platform is selected in the editor. Exit out of the Matinee editor and click on the Matinee that you just finished editing. In the Matinee's properties, check the Force Start Pos option and set the Force Start Position value to
Select the three sides of the first platform that we created (the static one) and hold Ctrl + G in order to group them together. With our platforms created, let's remove some of the elements that are no longer needed and the default floor by selecting it with the left mouse button and hitting Delete. In its place, duplicate the group that we just made and position it on the same Z value as the floor that was there previously. In the same way as we created the group of the static platform, we can also use this same mesh to create a staircase. Have each stair only be 16 units above the previous one and create a staircase leading up to the initial static platform.
Notice the capping mesh that I have placed covering the sides of the steps, otherwise they are likely to clip in and out of each other and look a bit gross.
Click on our initial static platform and duplicate it to create floors for the moving platforms section, so that if the player falls they will not die so early in the level. Take the same group and duplicate it to the left of the player's starting position twice. Ungroup the groups we created by holding Shift + G and remove the inner parts that aren't required, then hold Ctrl + G to recreate the larger group as a whole. Delete the unused sections.
The stairs work, but the camera moves jaggedly as we walk up or down on it. Thankfully, we have an easy solution, the BlockingVolume brush.
For those needing a refresher, a BlockingVolume is simply an invisible brush that blocks players and other actors from traveling the stairs, and we can create a volume that will make the player actually move up a ramp when it looks like he is going upstairs.
It doesn't matter for this project, but a BlockingVolume allows zero extent traces (projectiles, rockets, and so on) to go through it.
Click on the builder brush (the red square in our initial level) and open up Geometry Mode by either selecting it on the right side on the top row of the Modes toolbar, or by pressing Shift + 2. With it selected, create a shape like the following screenshot, by first extending the left side of the brush outward, then grabbing the top-left points and dragging downwards until it is only 16 units above the original. Right-click on the brush and select Add Volume | Blocking Volume. At this point if you would like to select all of the stairs, change their Collision Type to COLLIDE_NoCollision, though it will not change what the player interacts with.
Duplicate our large left sidepiece twice on the right-hand side with the tallest section being the jump height from the up and down moving platform's peak. From there, create another duplicate object around 864 units apart and in the middle, place a duplicate of our initial static platform to use.
Click on the LightmassImportanceVolume option (the yellow box), and use Geometry Mode to extend it to the space that we are using in the level.
For those wondering, Lightmass creates light maps with complex light interactions, making the level look more lifelike. It is orthogonal to the rest of the rendering pipeline (dynamic lighting and shadowing), meaning it just replaces the light maps and static shadow maps with higher-quality ones.
The LightmassImportanceVolume option in a level controls the area that Lightmass emits photons in, allowing you to concentrate it only on the area that needs detailed indirect lighting. Areas outside the importance volume get only one bounce of indirect lighting at a lower quality.
We have just replaced the default models in our level with different meshes to assemble parts that we can replicate. We also converted some of these meshes into Movers, and used Matinee in order to have our moving platforms actually move in the level using subsequences, which we can later turn into prefabs. We also created stairs that the player can climb while using BlockingVolumes in order to make the trip up less jarring.
As well as platforms, another staple of platformers is collectable items to reward players for exploring. We will implement two different types of collectable: items that the player may collect, and a power-up that will give the player the ability to double jump again.
Now let's start adding in those collectables!
Go to the Content Browser window by going to View | Browser Windows | Content Browser. In Content Browser, find the following particle system:
ParticleSystem'WP_ShockRifle.Particles.P_WP_ShockRifle_Ball'and click on it. Exit Content Browser and find a platform, right-click on it, and select Add Emitter: P_WP_ShockRifle_Ball. Hit the Real Time visualizer circled in the following screenshot or by pressing Ctrl + R to get a view of what our collectible will look like. Position the item in the air in a place that the player can reach by jumping, such as one of the previously mentioned positions the moving platform is travelling on.
Create a trigger around our new particle system by clicking on the builder brush. Right-click on the box selection on the Brushes toolbar and set the size of our builder brush to
64in the X, Y, and Z positions. Drag the box to fit around the emitter that we created in the previous step, by using the translate tool or by holding Ctrl and dragging it to where we want it to be. Keep in mind to have it positioned along the axis so that the player will actually be able to touch it.
Back in the Content Browser window, find the particle system
ParticleSystem'WP_ShockRifle.Particles.P_WP_ShockRifle_Explo'and add it slightly away from the first particle system. Inside its properties in Particle System Component, disable the Auto Activate option.
Open up the Kismet Editor and create a new subsequence by right-clicking and selecting Create New Sequence : 0 Objs. When the naming dialog comes up, type in
CoinPickupfor the Sequence Name field and press OK. Double-click on the sequence in order to enter it.
Outside Kismet, click on the trigger volume we created, then go back into Kismet. In our CoinPickup sequence, right-click and select New Event Using TriggerVolume_0 | Touch to create a Touch event for the Trigger. Create a variable under the Instigator output.
Next, create a Play Sound action on the right-hand side of the Touch event we just created by right-clicking and selecting New Action | Sound | Play Sound. Connect the Target input to Instigator from the TriggerVolume_0 Touch event that we created in the previous step.
Open up the Content Browser window and select the Sound Cue that you would like to play when you collect this item; I used
SoundCue'A_Pickups_Powerups.PowerUps.A_Powerup_UDamage_SpawnCue'. With that Sound Cue selected, exit out of the Content Browser window and go back into Kismet to our subsequence. Click on the green arrow to the right of the Play Sound variable called the Use selected object in Content Browser button and it should be filled with the sound we want to use.
Create a new Toggle Hidden action by going into New Action | Toggle | Toggle Hidden. Connect the Out output from the Play Sound action to the Hide connection of the Toggle Hidden action.
Now create a new Toggle event by selecting New Action | Toggle | Toggle. Connect the Out from the Toggle Hidden action to the Turn On connection on the Toggle action.
Close Kismet and in the UDK Editor click on the other particle system that we created (Emitter_1) and go back into Kismet. Right-click under the Target input and select New Object Var using Emitter_1.
At this point, we should have a single collectable that will hide our coin and will then play a sound as well as a particle system to inform the player what has happened. Now that we have created a single coin, let's make it extremely easy for us to create new coins with the same functionality. To do that, we will be using prefabs.
Rotate your screen so that the sky is in the air and you can clearly see the objects of our collectable without touching anything else. Move your mouse to the top left, slightly away from where the top left of the collectible's objects are. Hold Ctrl + Alt and drag down, right until the red rectangle is completely covering our collectable. This should select everything within the collectable. Alternatively, you could hold down Ctrl and click on each of the elements to select them.
The marquee selection
A marquee selection is a quick way to select or deselect a group of actors within a certain area. This type of selection involves holding down a combination of keys, clicking one of the mouse buttons, and dragging the mouse cursor to create a box (colored red). All the actors within the box will be selected or deselected depending on the combination of keys and the mouse button that is clicked. The possible combinations and their effects are:
Ctrl + Alt + click: Replaces the current selection with the actors contained in the box
Ctrl + Alt + Shift + click: Adds the actors contained in the box to the current selection
Ctrl + Alt + Shift + right-click: Removes any select actors in the box from the current selection
Right-click on the objects and select the Create Prefab... option. In the dialog box that comes up, put in
Hotshot01for the Package field and
Coinfor the Name section. After filling this out press the OK button. It will say that it found a sequence for the prefab. We say Yes to make the sequence part of the prefab and No to make the object an instance of the prefab. As soon as this happens, go to the Content Browser window and save our Hotshot01 package in the same folder as your level.
Take time to place some of these prefabs into your levels in areas that players may want to visit or entice players to travel a certain way. Be sure to build your game before you see if they work by selecting Build | Build All from the menu.
Note that some of these coins are obtainable with the player's default jump height. With that in mind, let's take our original actors to modify them for this new purpose.
Select the first emitter that we made on the collectable that is not currently a prefab. Press F4 to access its properties and change the Particle System Component's Template property to be
ParticleSystem'CTF_Flag_IronGuard.Effects.P_CTF_Flag_IronGuard_Idle_Red'. Have the other emitter use
ParticleSystem'VH_Scorpion.Effects.PS_Scorpion_Gun_Impact_Red'as its template.
Right-click on one of the two emitters and select Select Find Emitter_X in Kismet. To the right of our Toggle action, we want to create a Modify Property action by right-clicking and choosing New Action | Object Property | Modify Property from the menus. Expand Properties. In the Property Name variable type in
MaxMultiJump. Check the Modify Property option and change the value of Property Value to
1. Connect the Player variable to the Target input. Connect the Out output from the Toggle action to the In input of the Modify Property action.
Back in the UDK Editor, select all of the objects that make our "Double Jump" power-up and press Ctrl + G to create a group of it. We only want to have one of these in our level and we want to make it somewhat skill-based in order to get it as it opens new areas for people to explore.
Build your project by selecting Build | Build All. Save your game using File | Save All and run our game by selecting Play | In Editor.
We have just created the first two objects of our platformer world. We created them using two particle systems connected together by a trigger volume, which executes some simple code. Once we created the base coin, we were then able to easily create duplicates with the same functionality by utilizing the power of the prefab. After this, we took our original and modified the particles it used, and then had it change the overall functionality of the game, enabling the player to jump further. Not too bad!
Scott Rogers has a great primer on how to create effective platformer levels and how to place objects within the world called the Platformer Primer, which I recommend checking out if you want to start building levels of your own. The article is available at http://mrbossdesign.blogspot.sg/2008/10/platformer-primer.html.
Now that we have all of our mechanics in place, it would be a good time to spruce up our level a bit by adding some visual flair to it. In particular, we will be using the recent Landscape tool in order to build a backdrop for our level.
Click on the Landscape button under the Modes section of the left toolbar; this should cause the Landscape Edit window to open for us.
Once the Landscape Edit window comes up, it will have many options listed. We want to create a Heightmap, which we can now use within our level. In the Heightmap Size section, put in the values
64, and in the Component Size section select put 7 quads per component. Then click on the Create Landscape button.
For more details about how landscapes are created and how sizes and dimensions are figured, UDN has some great information for you, which can be found at:
After waiting for a period, you should see a large checker board-looking plane, which is our landscape. All the tools in the Landscape Edit window have tool tips telling you what they are, but to get the general feel of it in order to raise the level of whatever you are currently selecting, you can hold Ctrl down and click. To lower the size of something, you can hold Ctrl + Shift and click. To change the brush's size, there is a variable under Brushes called Brush Size.
Create hills in the background of our level and lower the value of the areas that are actually part of the platforming section of our level. Be careful that the edges are not visible on the far left or far right of the level.
Exit the Landscape mode and enter Camera Mode, and then click on our landscape. Press F4 to access the object's properties. Under Landscape in the Landscape Material variable, fill it with
Material'PivotPainterExamples.Materials.ground_Material'; feel free, however, to fill it with whatever material would be best for your particular level.
It is possible for you to blend multiple materials together to create some really cool effects. If this interests you, check out the tutorial at the following link:
We have now taken our level and added a nice touch of background to make the world much more realistic as well as grounded. Due to the colors we used, it is very easy for us to see our player, the platforms, and the objects to grab; and though the background is distant, it seems real.
In not much time, we have accomplished some very exciting things in UDK using just the Unreal Editor and Kismet to create a side-scrolling platform game. We created our own custom camera, which will follow our player when he is spawned, and modified the player with the use of the
.ini files and Kismet to create some very interesting features. We then created our level's environment, by first creating a static platform and then moving on to dynamic ones. With those created, we made collectibles that the player can obtain, as well as one that actually gives the player additional functionality. Finally, we used Landscape Mode to create a backdrop for our game world. Let's take one final look at what we have accomplished:
Our game is well on its way to being something special, but there are some things we could still add to make it even better! How about you take some time between projects and try to complete the following:
Add background music to our world and more sound effects
Add a door at the end of our level that will only open when we collect all of the coins in the level
Whenever our player dies, reset the camera's position
Create a basic enemy that will disappear if we jump on its head and move around in a fixed path
Add health to our player; if he misses the head when hitting an enemy, damage him