How to Create a Simple FPS in Unreal Engine 5

In this Unreal Engine 5 tutorial, you’ll create a simple first-person shooter while learning how to create a first-person character equipped with a gun, and you’ll learn how to apply damage to other actors in your game. By Ricardo Santos.

Login to leave a rating/review
Download materials
Save for later
Share

In this Unreal Engine 5 tutorial, you’ll create a simple first-person shooter while learning how to create a first-person character equipped with a gun, and you’ll learn how to apply damage to other actors in your game.

Update note: Ricardo Santos updated this tutorial for Unreal Engine 5. Tommy Tran wrote the original.

A first-person shooter (FPS) is a genre where the player uses guns and experiences the game through the eyes of a playable character. FPS games are immensely popular, with such well-known franchises as Call of Duty and Battlefield.

Unreal Engine was built to create FPS games, so it makes sense to create one using it. In this tutorial, you’ll learn how to:

  • Create a first-person Pawn that can move and look around.
  • Create a gun and attach it to the player Pawn.
  • Shoot bullets using a line trace — also known as a raycast.
  • Apply damage to actors.
Note: If this is your very first time using Unreal Engine, head over to our Getting Started tutorial to learn how to download the editor and navigate the interface.

Getting Started

Download the project materials with the Download Materials button at either the start or the end of this article, and unzip it. Navigate to the project folder called BlockBreakerStarter 5.0, and open BlockBreaker.uproject. You’ll see the following scene:

Initial view of the project on Unreal Engine 5 main window.

The green wall consists of multiple targets that turn red when they take damage. Once their health reaches zero, they disappear. The red button resets all the targets.

First, you’ll create the player’s Pawn.

Creating the Player Pawn

If you’re coming from UE4, you might’ve noticed that the folders panel seems to be missing. Despair not, as it’s hidden to allow an almost full-screen view of the project. To find the project folders, just click Content Drawer in the lower-left corner of the screen.

Content drawer in the lower-left corner of the screen.

Now, you can see the navigation panel, complete with the folder structure and game assets. If you’d like to have it permanently open at the bottom of your screen, simply click Dock in Layout on the right of this panel.

Content Drawer panel with Dock in Layout highlighted.

Navigate to the Blueprints folder and right-click the panel background to create a new Blueprint Class. Select Character as the parent class and name it BP_Player.

Creating a blueprint class in UE5

Character is a type of Pawn with additional functionalities, such as the CharacterMovement component that automatically handles movement like walking and jumping. You simply call the appropriate function, and it moves the Pawn. You can also set variables such as walk speed and jump velocity within this component.

Selecting Character Movement.

Before you can make the Pawn move, it needs to know when the player presses a movement key. To do this, you’ll map movement to the W, A, S and D keys.

Note: If you’d like to know about mappings, you can learn about them in this Blueprints Tutorial. Key mapping is how you define which keys will perform actions.

Creating Movement Mappings

With key mapping, you can alter an attribute of the player character — such as their position in the X-Y plane or the camera angle of the viewport — and apply it in the game world. This is how you manipulate character displacement and viewing angle.

Select Edit ▸ Project Settings and open the Input settings under the Engine section.

Project settings screen

Add two Axis Mappings by clicking the + next to Axis Mappings twice. You may have to expand the Axis Mappings list by clicking the expand triangle in front of Axis Mappings that appears after you add the first mapping. Rename them MoveForward and MoveRight. MoveForward will handle moving forward and backward. MoveRight will handle moving left and right.

Input menu where the key bindings are defined.

For MoveForward, change the key to W by first selecting the None dropdown list. Then, expand the Keyboard list, and finally, select the letter W right at the bottom of that list.

Key mapping

After that, create another key by clicking the + next to MoveForward, and set it to S. Change the Scale for S to -1.0.

Adjusting the scale in the key mappings, to move forward, the scale is 1.0 and to move backward, -1.0.

Note: If you’d like to learn more about the Scale field, you can refer to the same Blueprints Tutorial mentioned above. The Axis Value and Input Scale section describes what it is and how to use it.

Later, you’ll multiply the scale value with the Pawn’s forward vector. This will give you a vector that points forward if the scale is positive. If the scale is negative, the vector points backward. Using the resulting vector, you can make your Pawn move forward and backward.

Line graph showing how the scale value influences on the Character movement.

Next, you need to do the same for moving left and right. Change the key for MoveRight to D. After that, create a new key and set it to A. Change the Scale for A to -1.0.

Adjusting the scale in the key mappings, to move right, the scale is 1.0 and to move left, -1.0.

Now that you have the mappings set up, you need to use them to move.

Implementing Movement

Double-click BP_Player to open it, and you’ll see the Viewport view. Navigate to the Event Graph using the tabs at the top of the window.

EventGraph tab location on the UE5 editor window.

Right-click the view background to add a MoveForward event, the one listed under Axis Events. This event will execute every frame, even if you don’t press anything.

Creating the MoveForward blueprint node by right clicking on the screen background.

It also outputs an Axis Value, which is the Scale values you set earlier. It outputs 1 if you press W and -1 if you press S. If you don’t press either key, it outputs 0.

Move forward event node.

Next, you need to tell the Pawn to move. Add an Add Movement Input, and connect it like so:

Connecting the nodes to apply movement to the character.

Add Movement Input takes a vector and multiplies it by Scale Value, converting it to the appropriate direction. Since you’re using Character, the CharacterMovement component will move the Pawn in the appropriate direction.

Now, you need to specify which direction to move. Since you want to move forward, use Get Actor Forward Vector to return a vector pointing forward. Create one and connect it like so:

Setting the directions the character will move.

So, to summarize:

  • MoveForward runs every frame and outputs an Axis Value. This value is 1 if you press W and -1 if you press S. If you don’t press either, it’s 0.
  • Add Movement Input multiplies the Pawn’s forward vector with Scale Value. This causes the vector to point forward or backward, depending on which key you press. If you don’t press any key, the vector doesn’t have a direction, meaning the Pawn doesn’t move.
  • The CharacterMovement component gets the result from Add Movement Input and moves the Pawn in the appropriate direction.

Repeat the process for MoveRight, but replace Get Actor Forward Vector with Get Actor Right Vector.

The result after applying the same process to the moveRight event.

Before testing the movement, you need to set the default Pawn in the game mode.

Setting the Default Pawn

Click Compile in the window’s top-left corner, and go back to the main editor. Before you click it, it shows a yellow circle with a question mark. After clicking, it should have a green circle instead, showing that the process was successful.

Behavior of the Compile button

Open the World Settings panel and locate the Game Mode section. Change Default Pawn Class to BP_Player.

Field defining the main character class.

Note: If you don’t have the World Settings panel, go to Settings in the top-right corner of the window and click World Settings.
Alternate way to get to the World Settings dialog.

Now, you’ll automatically use BP_Player when the game starts, and it’s placed automatically in the position of the Player Start asset. Press Play and use the W, A, S and D keys to move around. You may have to click the mouse inside the game window first to give that window the keyboard focus.

And now, you can move!

Next, you’ll create mappings for looking around.

Creating Look Mappings

Open Project Settings again. Create two more Axis Mappings called LookHorizontal and LookVertical.

Creating the axis mapping for the mouse events to handle looking horizontally.

Change the key for LookHorizontal to Mouse X.

Creating the axis mapping for the mouse events to handle looking vertically.

This mapping outputs a positive value when you move the mouse right and vice versa.

Next, change the key for LookVertical to Mouse Y.

Defining the mouse input, considered to the camera movement.

This mapping outputs a positive value when you move the mouse up and vice versa.

Now, you need to create the logic for looking around.

Implementing Looking

If a Pawn doesn’t have a Camera component, Unreal automatically creates a camera for you. By default, this camera uses the rotation of the controller.

Note: If you’d like to learn more about controllers, check out this tutorial on Artificial Intelligence.

Even though controllers are non-physical, they still have their own rotation. This means you can make the Pawn and camera face different directions. For example, in a third-person game, the character and camera don’t always face the same direction.

Camera look applied to a third-person game.

To rotate the camera in a first-person game, you just need to change the rotation of the controller. It’s pretty much the same process you did for movement — you just use rotations instead of translations.

Open BP_Player and create a LookHorizontal event.

Invoking the event to treat the horizontal component of the mouse look interaction.

To make the camera look left or right, you need to adjust the controller’s yaw. Create an Add Controller Yaw Input and connect it:

Add controller yaw input

When you move the mouse horizontally, the controller yaws left or right. Since the camera is using the controller’s rotation, it also yaws.

Repeat the process for LookVertical, replacing Add Controller Yaw Input with Add Controller Pitch Input.

Connecting the mouse vertical input to the camera rotation node.

If you test the game right now, you’ll notice that vertical looking is inverted. This means when you move the mouse up, the camera looks down. If you prefer non-inverted controls, add a Multiply operator and multiply Axis Value by -1. This inverts Axis Value and controller pitching.

Inverting the mouse look.

Click Compile, and then press Play. Use your mouse to start looking around.

Looking around in the game world.

Now that you’re done with movement and looking, it’s time to create a gun!

Creating the Gun

You know how when you create a Blueprint Class, you can select a parent class? Well, you can also select your own Blueprints as a parent. This is useful when you have different types of objects that share common functionalities or attributes.

Say you want to have multiple types of cars. You can create a base car class containing variables such as speed and color. You can then create children classes that use the base car class as a parent. Each child will also contain the same variables. Now, you have an easy way to create cars with different speed and color values.

Variations of a car blueprint.

You can use the same method to create guns. You just need to create a base class first.

Creating the Base Gun Class

Go back to the main editor, and create a Blueprint Class of type Actor. Name it BP_BaseGun, and double-click to open it.

Next, you’ll create variables to define the gun properties. To do that, go to the Variables section of the blueprint window, and click the + button on the top-right of the frame.

Creating variables on the UE5 blueprint window.

Create the following float variables:

  • MaxBulletDistance: How far each bullet can travel.
  • Damage: How much damage to apply when a bullet hits an actor.
  • FireRate: How long before the gun can shoot another bullet, measured in seconds.

Defining the variables of the gun blueprint class.

Note: The default value for each variable is zero, which is fine for this tutorial. However, if you wanted new gun classes to have a default value, you’d set it in BP_BaseGun.

Now, you need a physical representation of the gun. Click Add, type Static Mesh, select the component Static Mesh to add it to the blueprint class, and name it GunMesh.

Adding the gun mesh component to the gun class.

Don’t worry about selecting a static mesh now. You’ll do this in the next section when you create a child gun class. In this parent class, you just define that a gun must have a static mesh component that displays the gun geometry in the game.

Creating a Child Gun Class

Click Compile, and go back to the main editor. To create a child class, right-click BP_BaseGun and select Create Child Blueprint Class.

Creating a child object of the gun class.

Name it BP_Rifle, and then open it. Open the Class Defaults at the top-right of the window, and set the variable values:

  • MaxBulletDistance: 5000
  • Damage: 2
  • FireRate: 0.1

Changing class defaults for the BP_Rifle class.

This means each bullet can travel a maximum distance of 5000. If it hits an actor, it deals 2 damage. When firing consecutive shots, the duration between each shot will be at least 0.1 seconds.

Next, you need to specify which mesh the gun should use. Select the GunMesh component on the left side of the screen, and notice that the Details tab on the right side has changed its contents. Look for the Static Mesh section and use the drop-down menu to set it to SM_Rifle.

Setting the BP_Rifle mesh.

The gun is complete. Click Compile, and close BP_Rifle.

Next, you’ll create your own camera component to give you better control of camera placement. It’ll also allow you to attach and keep the gun in front of the camera.

Creating the Camera

Open BP_Player, and add a Camera component the same way you created the Static Mesh component of the BP_BaseGun class. Name it FpsCamera.

Creating the FPS camera.

The default position is a bit too low, which might make the player feel small. On the Details panel, set the location of FpsCamera to (X:0, Y:0, Z:90).

FPS Camera positioning.

By default, Camera components don’t use the controller’s rotation. To fix this, go to the Details panel and enable Camera Options ▸ Use Pawn Control Rotation.

Defining the gun rotation as being the same as the Pawn's.

Next, you need to define the gun’s location.

Defining the Gun Location

To create the gun location, you’ll use a Scene component. These components are perfect for defining locations because they only contain a Transform. Make sure you have FpsCamera selected, and then add a Scene component to attach it to the camera. Name it GunLocation.

Attaching the gun to the FPS Camera.

By attaching GunLocation to FpsCamera, the gun will maintain the same position relative to the camera, always keeping the gun in view.

Next, in the Details panel, set the location of GunLocation to (X:30, Y:14, Z:-12) to place it to the front and slightly to the side of the camera.

Adjusting the position of the gun relative to the camera.

After that, set the rotation to (X:0, Y:0, Z:-95) to make it appear as though it’s aiming toward the center of the screen.

Adjusting the rotation of the gun relative to the camera.

Now, you need to spawn the gun and attach it to GunLocation.

Spawning and Attaching the Gun

Locate Event BeginPlay on the BP_Player event graph, create and connect a Spawn Actor From Class to it. Set Class to BP_Rifle.

Creating the node that spawns the gun when the game begins.

If you compile now, you’ll receive an error saying that the Spawn Transform node must have an input wired into it. This happens because, in the current form, this pin is a struct and needs proper initialization. To avoid this error, right-click Pawn Transform and select Split Struct Pin. This displays the variables that make up the pin and assigns initial values to them. Now the code compiles successfully.

Splitting node spawn transform.

Since you’ll need to use the gun later, you’ll store it in a variable, just as you created variables earlier for the base gun class. Now, create a variable of type BP_BaseGun, and name it EquippedGun.

Note: It’s important that the variable is not of type BP_Rifle. This is because the player can use different types of guns, not just the rifle. If you spawned a different type of gun, you wouldn’t be able to store it in a variable of type BP_Rifle. It would be like trying to fit a circle into a rectangular hole.

By making the variable of type BP_BaseGun, you’re creating a big hole that can accept many shapes.

Next, set EquippedGun to the Return Value of Spawn Actor From Class.

Getting a variable from the instantiated gun.

To attach the gun, you use an AttachActorToComponent. Create one and set Location Rule and Rotation Rule to Snap to Target to make the gun have the same location and rotation as its parent.

Creating the node that attaches the gun to the Character

Next, create a reference to GunLocation and connect everything:

Final blueprint script for creating a gun when the game begins.

So, to summarize:

  • When BP_Player spawns, it spawns an instance of BP_Rifle.
  • EquippedGun keeps a reference to the spawned BP_Rifle for later use.
  • AttachToComponent attaches the gun to GunLocation.

Click Compile, and then press Play. Now, you’ll have a gun when you spawn! When you look around, the gun will always be in front of the camera.

The gun following the camera's position and rotation.

Shooting Bullets

Now comes the fun part: shooting bullets! To check if a bullet hits something, you’ll use a line trace.

A line trace is a function that takes in a start and end point, which form a line. It then checks each point along the line, from start to finish, until it hits something. This is the most common method in games to check if a bullet hits something.

Since shooting is a function of guns, it should go in the gun class rather than the player. Open BP_BaseGun and create a function called Shoot by clicking the + at the top of the Functions panel, on the left side of the screen.

Creating a function in UE5 in a blueprint file.

After you enter the name of the Shoot function, UE5 should automatically open a blueprint tab for it on the center of the screen with a purple-colored Shoot node. If it doesn’t open automatically, double-click the newly created function on the left side panel.

Afterward, on the Input panel on the right side, click + to create two Vector inputs. Name them StartLocation and EndLocation to represent the start and end points of the line trace, which you’ll pass in from BP_Player. Notice that the Inputs are added to the Shoot node, just like function arguments.

Defining the start and the end positions of the gun range.

You can perform a line trace using a LineTraceByChannel. This node checks for hits using the Visibility or Camera collision channel. Create one and connect it:

Defining the raytrace node used to determine if an object was shot.

Next, you need to check if the line trace hit anything. Create a Branch and connect it:

Determining if the line trace hit a target.

Return Value outputs true if there was a hit and a false otherwise.

Next, to give the player visual feedback on where the bullet hit, you’ll use a particle effect.

Spawning Bullet Impact Particles

First, you need to get the location of the trace hit. Drag-click on Out Hit and release left-click in the graph. From the menu, select Break Hit Result.

Getting more information from the hit result.

This gives you a node with various pins relating to the result of the line trace.

Create a Spawn Emitter at Location and set Emitter Template to PS_BulletImpact. Then, connect its Location to Location of Break Hit Result.

Setting the particle emitter and spawning it in the correct location.

Here’s the function so far:

The full result of the process to spawn a particle emitter.

So, to summarize:

  • When Shoot executes, it performs a line trace using the provided start and end points.
  • If there was a hit, Spawn Emitter at Location spawns PS_BulletImpact at the hit location.

Now that the shooting logic is complete, you need to use it.

Calling the Shoot Function

First, you need to create a key mapping for shooting. Click Compile and open Project Settings. Create a new Axis Mapping called Shoot. Set its key to Left Mouse Button, and then close Project Settings.

Input mapping to the mouse shoot event.

Next, open BP_Player, and create a Shoot event.

Adding the shoot event.

To check if the player is pressing the Shoot key, you just need to check if Axis Value equals 1. Create the highlighted nodes. One is a Branch, the other is an Equal operator:

Verifying the state of the button pressed.

Next, create a reference to EquippedGun, and then call its Shoot function.

Add two more nodes

Now, you need to calculate the start and end points for the line trace.

Calculating the Line Trace Locations

In many FPS games, the bullet starts from the camera rather than the gun, as the camera is already perfectly aligned with the crosshair. So if you shoot from the camera, the bullet is guaranteed to go where the crosshair is.

Note: Some games do shoot from the gun. However, it requires extra calculations to shoot toward the crosshair.

Still in the BP_Player Blueprint Class, create a GetWorldLocation (FpsCamera).

Getting the location of the camera.

Next, you need to add a GetForwardVector to the FpsCamera. Click-drag from the FpsCamera and type getforwardvector.

Added a get forward vector node

Now, you need the end location. Guns have a MaxBulletDistance variable, so the end location must be MaxBulletDistance units from the camera. Click the EquippedGun variable and drag it into the blueprint graph, and click-drag out of this node. Then, type Max Bullet Distance, and select it in the window. To perform the mathematical calculations needed, click-drag from Max Bullet Distance, type * to create the multiplication node, click-drag from the multiplication node and type + to create the add node. The process should look like this:

Creating and connecting nodes

Then, finalize by connecting the nodes:

Calculating the shot distance for hitting something.

After that, connect everything:

Connecting all nodes

So, to summarize:

  • When the player presses or holds left-click, the gun shoots a bullet starting from the camera.
  • The bullet travels forward by the distance specified by MaxBulletDistance.

Click Compile, and then press Play. Hold left-click to start shooting.

Gun shooting without interval between bullets.

Currently, the gun shoots in every frame. That’s too fast, so the next step is decreasing the gun’s fire rate.

Decreasing the Fire Rate

First, you need a variable to decide if the player can shoot. Open BP_Player and create a Boolean variable named CanShoot. Set its default value to true. If CanShoot equals true, the player can shoot and vice versa.

Drag the CanShoot variable into the blueprint graph and place a node to get its value. Click-drag from this variable, type AND, and select the corresponding logical operation. Change the Branch section to:

Verifying if the player can shoot.

Now, the player can only shoot if the Shoot key is being pressed and CanShoot equals true.

After the gun shoots, it needs a cooldown time. So, you need to add some more nodes after the Shoot function. To do that, click-drag from the arrow on the Shoot function call, and type CanShoot to add a SetCanShoot node. Make sure to leave the checkbox on this node unchecked to set the variable to false. Next, click-drag from the SetCanShoot arrow, add a Delay node and a SetCanShoot node. Now, make sure the checkbox is checked to set the variable to true, allowing the next shot to be fired. Remember that the gun has a FireRate variable? Get the FireRate variable from EquippedGun the same way you got MaxBulletDistance. The final result should look like this:

Adjusting the gun rate of fire.

You’ve just made the following changes:

  • The player can only shoot if holding left-click and CanShoot equals true.
  • Once the player shoots a bullet, CanShoot is set to false. This prevents the player from shooting again.
  • CanShoot is set back to true after the duration provided by FireRate.

Click Compile, and then close BP_Player. Press Play, and test out the new fire rate.

New player shoot rate.

Next, you’ll make the targets and button respond to bullets by applying damage to them.

Applying Damage

In Unreal, every actor has the ability to receive damage. However, it’s up to you to decide how the actor responds to it.

For example, when receiving damage, a fighting game character would lose health. However, something like a balloon wouldn’t have health — you’d program it to pop when receiving damage.

Before you handle how the actor receives damage, you first need to apply damage. Open BP_BaseGun, and add an Apply Damage at the end of the Shoot function.

The Apply Damage node.

Next, you need to specify that the actor hit by the line trace should receive damage. Connect Damaged Actor to Hit Actor of the Break Hit Result.

Connecting the Apply Damage node with the rest of the blueprint code.

Finally, you need to specify how much damage to apply. Get a reference to Damage and connect it to Base Damage.

Selecting how much damage should be dealt to the other character.

Now, when you call Shoot, it will damage any actors hit by the line trace. Click Compile, and then close BP_BaseGun.

Now, you need to handle how each actor receives damage.

Handling Damage

First, you’ll handle how the targets take damage. Open BP_Target, and create an Event AnyDamage. This event executes whenever the actor receives damage that’s not zero.

Preparing the targets to receive damage.

Next, call the TakeDamage function and connect the Damage pins. This subtracts health from the target’s Health variable and updates the target’s color.

Receiving damage from being shot.

Now, when the target takes damage, it loses health. Click Compile, then close BP_Target.

Next, you need to handle how the button takes damage. Open BP_ResetButton and create an Event AnyDamage. Then, call the ResetTargets function.

Getting the reset button to respond to damage.

This resets all the targets when the button receives damage. Click Compile, and then close BP_ResetButton.

Press Play, and start shooting the targets. To reset the targets, shoot the button.

The final project functioning

Where to Go From Here?

You can download the completed project files by clicking Download Materials at the top or bottom of the tutorial.

You now have an FPS base that you can easily expand on. Try creating more guns with different types of fire rates and damage. Maybe try adding reload functionality too!

We hope you enjoyed this tutorial, and if you have any questions or comments, please join the forum discussion below!