Creating an Adventure Game Level
In this tutorial, you will create a level for an adventure puzzle game.
Elements of an Adventure Game
Understand the elements of an adventure game.
Not every game has to feature defeating enemies. For this game, you will create a game where the player needs to solve puzzles and get to a final destination.
There will be various obstacles that block the players path they will need to overcome. Some challenges will be physical, such as jumping from platform to platform. Other challenges will be mental, the player will need to solve a puzzle to continue.
Download this template project to get started: Adventure Template Project
After opening up the project, open the BaseScene scene, which has a basic terrain set up already.
Player and Victory Destination
Set up a player and victory condition
The first part of the game will be placing the player and the place they need to go to win the game or go to the next level.
The FPS Controller is already in the scene with the tag of "Player", along with a basic terrain. We'll place objects in the scene on this terrain, but once you finish the game you will be free to alter the terrain and design a more interesting level.
You will need to indicate to the player this is where they need to go. There's a lot of ways you can indicate this. One way is already present on the terrain: there's a path that leads away from where the player starts, which indicates that's where the player should go.
To give even more indication of where the player should go, you're going to add a colorful column the player can see, as well as some particle effects to make the destination really stand out against the terrain.
Create a Cylinder object, rename it
Destinationand make it big enough for the player to notice, even if it was behind a mountain. Then, place it at the end of the path.
Create a material inside the Materials folder and make it a noticeable color, as well as make it semi-transparent. Then add that material to the cylinder.
Create a particle effect and add it to the column. Change it to be a sphere so it radiates from the center.
Next, you'll set up the code for the destination.
Inside the Scripts folder in the project, find the VictoryDestination script and attach it to the Destination object. Then set the capsule collider of that object to be a trigger.
Then, inside the Prefabs folder, find the VictoryCanvas Prefab and place it on the scene.
You'll notice that the VictoryDestination script has two variables, one called Next Scene and one called Win Screen.
This code allows two options. If you want the player to go to a different scene, you can enter the scene name in that field. But in our current game, we only have one level.
By placing the VictoryCanvas object into the Win Screen field, it will display that canvas when the player reaches the destination.
Connect the VictoryCanvas object to the destination, and try out the game.
In making an adventure game, you always need to think about how you're directing the player to get to where they need to go. A giant pillar with particle effects is one way to do that, but there's plenty of other ways you could do it.
Make the player jump to reach a destination
Next, you'll make the player work a little bit to get to the goal. Adding platforms gives the player a challenge.
Think about how hard you want your game to be for the player. Not very challenging? Maybe just a few, large, close-together platforms. If you want the game to be more challenging, make the platforms smaller and further apart.
It's easy to make platforms. Create one cube and size it to make it a platform. Then duplicate it and move it to set the next platform up. You can also make a prefab out of platforms and drag them to your scene, if you want.
Lastly, move the destination to the top of your collection of platforms. Now the player has to complete the jumping challenge to reach the destination.
When designing levels with platforms it's important not to punish the player too badly when they fail. Considering dividing the level into sections with gates. Once the player passes one section, they won't have to repeat it if they mess up.
If you want to get more creative with jump possibilities, increase the Jump Speed field inside the FPSController's First Person Controller script.
Adding a Door
Add a door that opens when the player presses a button
If the player only has to follow one direct path, the level might get a little boring. We can block an exit until the player presses a button.
In the next section of the terrain, after the platform section, you'll add a door and a button based on a prefab. Then, you'll link the button to the door.
Inside the Prefabs folder, find the DoorSetup Prefab, and drag it into the scene, placing it in between the two mountains.
Next, find the DoorButton Prefab, and place it somewhere inside of the section. Then, create two materials. One material will display when the button has not been pressed, and one will display when the button has been pressed. A common convention is to use the color Red for an unpressed button, and Green for a pressed button.
Link the button's door field to the door, and the material fields to the activated and deactivated materials.
When making an adventure game, you can gate off sections to prevent the player from returning to old parts of the level, but you have to make sure the player always has what they need to get to the end of the level.
Lastly, move the FPSController and the Destination so that the player starts on one side of the door, then goes to the other side to win.
Consider your design: train your player on how buttons and doors work. The first time the player sees a door with a button, place the button right next to the door. But for the next door, put the button somewhere that the player will need to explore to find it. After the first door, the player should already understand they need to press a button to open the door, so they'll know to go looking for it if they don't see it right away.
Adding a Closing Door
Add a door that opens when the player stands on a button, and closes when they move off the button
Right now, the door will open when the player presses the button. But there are ways that you can make it more interesting for the player.
To change things up a bit, we'll have the door move up when the player stands next to the button...but start dropping down when the player moves away!
In the ButtonTrigger script, click the checkbox for Continuous Required
After you've done that, play around with the speed of the door in the Door script. The player will have a limited amount of time to get to the door before it closes. You can make it harder by increasing the Door Move Speed or easier by decreasing the Door Move Speed.
With the system you have, you can create as many buttons as you want and have them all connect to the same door. Just add another button and hook up the door to the button's script.
Ready for a fun combo? Create a door that closes after the player walks away...but make the door at the top of a series of platforms! That way, there's some time pressure for the player to reach the door before time runs out.
Technically, there's nothing stopping you from having the door move horizontally rather than vertically. That way, you can create a platform the player needs to jump on at just the right time to get to the next section, before it moves back to its starting location. Get creative!
Adding Object Pick-Up
Give the player the ability to pick up objects and uses them to place on the button to open a door.
How about we give the player a new ability? Right now we have the player stand next to the button to activate it. But we can also have the player place an item on the button to open it.
First, add an empty object as a child of the FPSController, and move the transform to be slightly in front of the camera. Call it
HoldLocation, this will be where the object will be held when the player is holding it.
Add a cube to the level, then add the PickUp script and a Rigidbody component to the cube. Inside the script, set the Hold Transform field to be the transform you created as a child of the FPSController.
Now, when you go to the object and hold down the mouse while looking at it, you will pick it up. When you let go of the mouse, you will drop the object.
This object can now be placed on a switch to open the door. When it is taken off the switch, the door will close.
Cheesinga level is a way to refer to players who break the intended way to play your level)
If you have multiple doors that are opened through putting items on buttons, and you provide multiple items in one section, beware of players trying to break your level.
Once players understand that carrying items can give them benefits, they will usually carry them from one section to the next, to be prepared just in case they see another door.
If you want to use multiple doors, make sure there's only one item available to open each door.
Also, watch out if your door closes too slowly. Your player might try to take the item with them! Make sure you test to make sure the player can't break your level in a way you don't intend.
Adding a Key-based Button
Add a door that opens when the player gives a key to a button.
Instead of the player putting an object on the button, we can have them find a very specific object that will open the door.
Take one of the pick up objects you created, and drag it into the Key Required field of the ButtonTrigger object. Then, make sure Continuous Required is unchecked.
Now, you can no longer stand on the trigger to open the door, you have to put the object on the trigger to open the door.
Or, if there's no way to prevent the player throwing away the key, you will need to code a way for the key to respawn if it becomes lost, or add multiple keys at the same location in case the player .
One other condition to watch out for: the code for managing keys destroys the key after it is delivered to the button. So don't require the button to be continuous, otherwise it won't work! (Or, if you're adventurous, you can always look at the code yourself and adjust it to your liking.)
Design notes: If you're going to require an object as a key, make sure that it's clear to the player what object they'll need. Give the key a unique shape and color, and have that match information around the button.
You can always put the button trigger on the door object itself. That way, after the key is inserted, the door will open and take the button with it.
Adding a Basic Portal
Add a portal to get the player from one place in the level to another
There's a design problem in adventure games that all of them need to solve at one point or another: if the player gets to the end of a dungeon, how do they get back out?
One way to solve this problem is called a looping design. That is, there's a door that goes straight from the end of the level to the beginning...but you need the key located at the end to open it!
The challenge with this is that you would need to design your level as one big circle. If that level design method isn't going to work well for your game, you can always use a teleport system.
Sometimes it's useful to be able to teleport a player from one place in the level to another. We'll create a teleport system that allows a player to walk through a portal to a different place in the level.
Create two objects. The first object will be a cube shaped like a doorway, call it
Portal. The second object will just be an empty object transform, call it
PortalDestination. Place them at different places in the level
Add the PortalTeleporter script to the Portal, and turn the Box Collider into a trigger. Then, put the FPSController object in the Player field, and the PortalDestination in the Receiver field.
Now, walk to the Portal and you'll instantly be transported to the destination.
Design Note: You might want to provide the player some indication about where the portal will transport them before they enter it. You don't have to use text, specifically. Going to a snowy area? Put a bunch of snow terrain around the portal!
Adding a See-Through Portal
Add a portal that the player can see through.
Teleportation is one thing, but to kick things up a notch you can have the player see where they'll be teleported before the get there.
The setup for this feature is a little complicated, so you'll just use a prefab starter to get it working. Find the PortalSetup prefab and drag it out to the scene.
Now, move the portals to where you want them to be. Note: If you want to rotate the portals, make sure you rotate both of them by the same amount.
We have to adjust some settings on the player camera. Find the FirstPersonCharacter object that is underneath the FPSController.
Add a Post-Processing Behavior component to that object, and set the Profile to CC (PostProcessingProfile)
Now, find the Camera_A and Camera_B objects, and set the Player Camera field to FirstPersonCharacter.
Lastly, find the two ColliderPlane objects, and set the Player fields to FPSController.
Now, try out your portals!
Technical Note: Now that you've performed the initial setup on the prefab inside of your scene, you can duplicate that prefab inside of your scene if you want to add more portals.
Design Note: The player can carry items through portals. You can create a level where players have to go through different sets of portals to find a key for a door. To make things more interesting, force the player to take a different route coming back through portals than the way they went through them to get to the key.
Designing an Adventure Game - Additional Tips
Here are some additional tips when building an adventure game
Decide on a theme
There are lots of different themes you could go with for an adventure game. You could explore an alien planet, or an ancient template, or even a city.
If the player understands the theme of the level, it will go a long way towards them wanting to reach the end of the level and wanting to see what happens at the end.
Try to think of ways you can tell a story through adding objects to the level.
Direct the player, but don't railroad them
If you make a wide open level, the player might not know which way to go. It's usually better to set up a level with obvious paths for the player to follow.
In addition, you can set up gates to your sections so that the player can't wander back to old sections if they already found the way out.
Make sure that you add landmarks to your level. This can be a special-looking tree or building, or changing the terrain of a section. That way, the player knows if they've visited that section before.
Another good way to indicate where the player should go is to add collectibles that guide the player along a path.
However, make sure that you don't just include one very direct path to the goal. If there's nothing to explore in the level, the player might get bored.
The bottom line is: You always want the player to know WHAT they have to do next, and leave HOW to do it up to them.
There's nothing that says you can't use this code with the FPS code. Adding keys and doors to your FPS that you created can add a new level of interest and adventure for your players.