We will be creating a first person shooter; however, instead of shooting a gun to damage our enemies, we will be shooting a picture in a survival horror environment; similar to the Fatal Frame series of games and the recent indie title DreadOut. To get started on our project, we're first going to look at creating our level or, in this case, our environments starting with the exterior.
In the game industry, there are two main roles in level creation: the environment artist and level designer.
An environment artist is a person who builds the assets that go into the environment. He/she uses tools such as 3ds Max or Maya to create the model,
and then uses other tools such as Photoshop to create textures and normal maps.
The level designer is responsible for taking the assets that the environment artist has created and assembling them into an environment for players to enjoy. He/she designs the gameplay elements, creates the scripted events, and tests the gameplay. Typically, a level designer will create environments through a combination of scripting and using a tool that may or may not be in development as the game is being made. In our case, that tool is Unity.
One important thing to note is that most companies have their own definition for different roles. In some companies, a level designer may need to create assets and an environment artist may need to create a level layout. There are also some places that hire someone to just do lighting, or just to place meshes (called a mesher) because they're so good at it.
(For more resources related to this topic, see here.)
In this article, we take on the role of an environment artist whose been tasked with creating an outdoor environment. We will use assets that I've placed in the example code as well as assets already provided to us by Unity for mesh placement. In addition to this, you will also learn some beginner-level design.
This project will be split into a number of tasks. It will be a simple step-by-step process from the beginning to end. Here is an outline of our tasks:
At this point, I assume you have a fresh installation of Unity and have started it. You can perform the following steps:
Once completed, click on Create. Here, if you see the Welcome to Unity pop up, feel free to close it as we won't be using it.
Now just because we are going to be diving straight into Unity, I feel it's important to talk a little more about how level design is done in the gaming industry. While you may think a level designer will just jump into the editor and start playing, the truth is you normally would need to do a ton of planning ahead of time before you even open up your tool.
Generally, a level design begins with an idea. This can come from anything; maybe you saw a really cool building, or a photo on the Internet gave you a certain feeling; maybe you want to teach the player a new mechanic. Turning this idea into a level is what a level designer does. Taking all of these ideas, the level designer will create a level design document, which will outline exactly what you're trying to achieve with the entire level from start to end.
A level design document will describe everything inside the level; listing all of the possible encounters, puzzles, so on and so forth, which the player will need to complete as well as any side quests that the player will be able to achieve. To prepare for this, you should include as many references as you can with maps, images, and movies similar to what you're trying to achieve. If you're working with a team, making this document available on a website or wiki will be a great asset so that you know exactly what is being done in the level, what the team can use in their levels, and how difficult their encounters can be. Generally, you'll also want a top-down layout of your level done either on a computer or with a graph paper, with a line showing a player's general route for the level with encounters and missions planned out.
Of course, you don't want to be too tied down to your design document and it
will change as you playtest and work on the level, but the documentation process
will help solidify your ideas and give you a firm basis to work from.
For those of you interested in seeing some level design documents, feel free to check out Adam Reynolds (Level Designer on Homefront and Call of Duty: World at War) at http://wiki.modsrepository.com/index.php?title=Level_Design:_Level_Design_Document_Example.
If you want to learn more about level design, I'm a big fan of Beginning Game Level Design, John Feil (previously my teacher) and Marc Scattergood, Cengage Learning PTR. For more of an introduction to all of game design from scratch, check out Level Up!: The Guide to Great Video Game Design, Scott Rogers, Wiley and The Art of Game Design, Jesse Schell, CRC Press.
For some online resources, Scott has a neat GDC talk called Everything I Learned About Level Design I Learned from Disneyland, which can be found at http://mrbossdesign.blogspot.com/2009/03/everything-i-learned-about-game-design.html, and World of Level Design (http://worldofleveldesign.com/) is a good source for learning about level design, though it does not talk about Unity specifically.
When creating exterior environments, we cannot use straight floors for the most part, unless you're creating a highly urbanized area. Our game takes place in a haunted house in the middle of nowhere, so we're going to create a natural landscape. In Unity, the best tool to use to create a natural landscape is the Terrain tool. Unity's terrain system lets us add landscapes, complete with bushes, trees, and fading materials to our game.
To show how easy it is to use the terrain tool, let's get started.
The first thing that we're going to want to do is actually create the terrain we'll be placing for the world. Let's first create a terrain by navigating to GameObject | Create Other | Terrain:
If you are using Unity 4.6 or later, navigate to GameObject | Create General | Terrain to create the Terrain.
At this point, you should see the terrain. Right now, it's just a flat plane, but we'll be adding a lot to it to make it shine. If you look to the right with the Terrain object selected, you'll see the Terrain Editing tools, which can do the following (from left
to right):
By default, the entire terrain is set to be at the bottom, but we want to have some ground above and below us; so first, with the terrain object selected, click on the second button to the left of the terrain component (the Paint Height mode). From here, set the Height value under Settings to 100 and then click on the Flatten button. At this point, you should notice the plane moving up, so now everything is above
by default.
Next, we are going to add some interesting shapes to our world with some hills by painting on the surface. With the Terrain object selected, click on the first button to the left of our Terrain component (the Raise/Lower Terrain mode). Once this is completed, you should see a number of different brushes and shapes that you can select from.
Our use of terrain is to create hills in the background of our scene so that it does not seem like the world is completely flat.
Under the Settings area, change the Brush Size and Opacity values of your brush to 100 and left-click around the edges of the world to create some hills. You can increase the height of the current hills if you click on top of the previous hill. This is shown in the following screenshot:
When creating hills, it's a good idea to look at multiple angles while you're building them, so you can make sure that none are too high or too short. Generally, you want to have taller hills as you go further back, otherwise you cannot see the smaller ones since they would be blocked.
In the Scene view, to move your camera around, you can use the toolbar in the top right corner or hold down the right mouse button and drag it in the direction you want the camera to move around in, pressing the W, A, S, and D keys to pan. In addition, you can hold down the middle mouse button and drag it to move the camera around. The mouse wheel can be scrolled to zoom in and out from where the camera is.
Even though you should plan out the level ahead of time on something like a piece of graph paper to plan out encounters, you will want to avoid making the level entirely from the preceding section, as the player will not actually see the game with a bird's eye view in the game at all (most likely). Referencing the map from the same perspective of your character will help ensure that the map looks great.
To see many different angles at one time, you can use a layout with multiple views of the scene, such as the 4 Split.
Once we have our land done, we now want to create some holes in the ground, which we will fill in with water later. This will provide a natural barrier to our
world that players will know they cannot pass, so we will create a moat by first changing the Brush Size value to 50 and then holding down the Shift key, and
left-clicking around the middle of our texture. In this case, it's okay to use the Top view; remember this will eventually be water to fill in lakes, rivers, and so on, as shown in the following screenshot:
At this point, we have done what is referred to in the industry as "greyboxing", making the level in the engine in the simplest way possible but without artwork (also known as "whiteboxing" or "orangeboxing" depending on the company you're working for).
At this point in a traditional studio, you'd spend time playtesting the level and iterating on it before an artist or you takes the time to make it look great. However, for our purposes, we want to create a finished project as soon as possible. When doing your own games, be sure to play your level and have others play your level before you polish it.
For more information on greyboxing, check out http://www.worldofleveldesign.com/categories/level_design_tutorials/art_of_blocking_in_your_map.php.
For an example with images of a greybox to the final level, PC Gamer has a nice article available at http://www.pcgamer.com/2014/03/18/building-crown-part-two-layout-design-textures-and-the-hammer-editor/.
This is interesting enough, but being in an all-white world would be quite boring. Thankfully, it's very easy to add textures to everything. However, first we need to have some textures to paint onto the world and for this instance, we will make
use of some of the free assets that Unity provides us with.
So, with that in mind, navigate to Window | Asset Store.
With this, we already have a level that looks pretty nice! However, that being said, it's just some hills. To really have a quality-looking title, we are going to need to do some additional work to beautify the environment.
We now have a base for our environment with the terrain, but we're still missing a lot of polish that can make the area stand out and look like a quality environment. Let's add some of those details now:
You have to use a Capsule Collider in order to have the collision carried over to the terrain.
This aspect of level creation isn't very difficult, just time consuming. However, it's taking time to enter these details that really sets a game apart from the other games. Generally, you'll want to playtest and make sure your level is fun before performing these actions; but I feel it's important to have an idea of how to do it for your future projects.
At this point, we have a nice exterior shape created with the terrain tools!
If you want to add even more detail to your levels, you can add additional trees and/or materials to the level area as long as it makes sense for them to be there.
For more information on the terrain engine that Unity has, please visit http://docs.unity3d.com/Manual/script-Terrain.html.
Now that we have the terrain and its details, it's hard to get a good picture of what the game looks like without being able to see what it looks like down on the surface, so next we will do just that. However, instead of creating our player from scratch as we've done previously, we will make use of the code that Unity has provided us. We
will perform the following steps:
If you are using Unity 4.6 or later, navigate to GameObject | Create General | Terrain to create the Terrain.
At this point, we have a playable level that we can explore and move around in!
Now, the base of our world has been created; let's add some effects to make the
game even more visually appealing and so it will start to fit in with the survival horror feel that we're going to be giving the game.
The first part of creating the atmosphere is to add something for the sky aside from the light blue color that we currently use by default. To fix this, we will be using a skybox. A skybox is a method to create backgrounds to make the area seem bigger than it really is, by putting an image in the areas that are currently being filled with the light blue color, not moving in the same way that the sky doesn't move to us because it's so far away.
The reason why we call a skybox a skybox is because it is made up of six textures that will be the inside of the box (one for each side of a cube). Game engines such as Unreal have skydomes, which are the same thing; but they are done with a hemisphere instead of a cube. We will perform the following steps to build the atmosphere:
If for some reason, you'd like to make the world pitch black, you'll need to modify the Ambient Light property to black inside the RenderSettings section. By default, it is dark grey, which will show up even if there are no lights placed in the world.
In the preceding example, I increased the Intensity value to make it easier to see the world to make it easier for readers to follow, but in your project, you probably don't want the player to see so far out with such clarity.
With this, we now have a believable exterior area at night! Now that we have this basic knowledge, let's add a flashlight so the players can see where they are going.
Now that our level looks like a dark night, we still want to give our players the ability to see what's in front of them with a flashlight. We will customize the First Person Controller object to fit our needs:
If you have Unity Pro, you can also give shadows to the world based on your lights by setting the Shadow Type property.
We now have a flashlight, so the player can focus on a particular area and not worry.
Now the flashlight looks fine in a screenshot, but if you walk throughout the world, it will feel very static and unnatural. If a person is actually walking through the forest, there will be a slight bob as you walk, and if someone is actually holding a flash light, it won't be stable the entire time because your hand would move. We can solve both of these problems by writing yet another script. We perform the following steps:
using UnityEngine;
using System.Collections;
/// <summary>
/// Allows the attached object to bob up and down through
/// movement or
/// by default.
/// </summary>
public class BobbingAnimation : MonoBehaviour
{
/// <summary>
/// The elapsed time.
/// </summary>
private float elapsedTime;
/// <summary>
/// The starting y offset from the parent.
/// </summary>
private float startingY;
/// <summary>
/// The controller.
/// </summary>
private CharacterController controller;
/// <summary>
/// How far up and down the object will travel
/// </summary>
public float magnitude = .2f;
/// <summary>
/// How often the object will move up and down
/// </summary>
public float frequency = 10;
/// <summary>
/// Do you always want the object to bob up and down or
/// with movement?
/// </summary>
public bool alwaysBob = false;
/// <summary>
/// Start this instance.
/// </summary>
void Start ()
{
startingY = transform.localPosition.y;
controller = GetComponent<CharacterController> ();
}
/// <summary>
/// Update this instance.
/// </summary>
void Update ()
{
// Only increment elapsedTime if you want the player to
// bob, keeping it the same will keep it still
if(alwaysBob)
{
elapsedTime += Time.deltaTime;
}
else
{
if((Input.GetAxis("Horizontal") != 0.0f) ||
(Input.GetAxis("Vertical") != 0.0f) )
elapsedTime += Time.deltaTime;
}
float yOffset = Mathf.Sin(elapsedTime * frequency) *
magnitude;
//If we can't find the player controller or we're
// jumping, we shouldn't be bobbing
if(controller && !controller.isGrounded)
{
return;
}
//Set our position
Vector3 pos = transform.position;
pos.y = transform.parent.transform.position.y +
startingY + yOffset;
transform.position = pos;
}
}
For more information on sine waves, visit
http://en.wikipedia.org/wiki/Sine_wave.
To learn more about FPS game, the following books published by Packt Publishing (https://www.packtpub.com/) are recommended:
Building an FPS Game with Unity (https://www.packtpub.com/game-development/building-fps-game-unity)
Further resources on this subject: