
This is what you'll see at the end of this section.
Goals
The purpose of this section is to show you how to implement your First Person Shooter character.
Objectives
By the end of this section of the tutorial, you will be able to:
- Make a New Character
- Set Up Axis Mapping
- Implement Character Movement Functions
- Implement Mouse Camera Control
- Implement Character Jumping
- Add a Mesh to Your Character
- Change the Camera View
- Add a First Person Mesh to Your Character
Steps
- 2.1 - Making a New Character
- 2.2 - Setting up Axis Mapping
- 2.3 - Implementing Character Movement Functions
- 2.4 - Implementing Mouse Camera Control
- 2.5 - Implementing Character Jumping
- 2.6 - Adding a Mesh to Your Character
- 2.7 - Changing the Camera View
- 2.8 - Add a First Person Mesh to Your Character
2.1 - Making a New Character
During this step, you are going to make a new character in the Unreal Engine (UE) using the engine's Character base class. The Character class (derived from the Pawn class) has built-in functionality for bipedal movement such as walking, running, and jumping.
Adding a Character Class
Although you can manually add .h and .cpp files to your Visual Studio (VS) solution, it is good practice to use the C++ Class Wizard to add new classes to your project.
By using the C++ Class Wizard, the engine creates header and source templates that set-up Unreal specific macros for you.
-
Launch your FPS project in UE (if you have not already done so).
-
In the File menu, select New C++ Class... to choose your new parent class.
-
The Choose Parent Class menu will open. Scroll down, select Character as the parent class, and click Next.
-
Name the new class "FPSCharacter" then click Create Class.
Verifying the Character Class
-
In the Solution Explorer of VS, expand FPSProject > Source > FPSProject.
-
Click
FPSCharacter.cpp
to open the implementation file for your FPSCharacter class. -
Add the following lines of code in the
BeginPlay()
function (underSuper::BeginPlay();
) to verify thatFPSCharacter
class is being used:
check(GEngine != nullptr);
// Display a debug message for five seconds.
// The -1 "Key" value argument prevents the message from being updated or refreshed.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
FPSCharacter.cpp
should now look like the following:
// Copyright Epic Games, Inc. All Rights Reserved.
#include "FPSCharacter.h"
// Sets default values
AFPSCharacter::AFPSCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AFPSCharacter::BeginPlay()
{
Super::BeginPlay();
check(GEngine != nullptr);
// Display a debug message for five seconds.
// The -1 "Key" value argument prevents the message from being updated or refreshed.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
}
// Called every frame
void AFPSCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
-
Save the
FPSCharacter
CPP file in Visual Studio. -
Locate FPSProject in the Solution Explorer.
Up until now, you have been compiling your project using the editor's Build button. During this step, you are going to gain experience compiling code using Visual Studio's build feature. To compile your code from inside Visual Studio, right-click on FPSProject and select Build to compile your project.
-
To compile your code from inside VS, right-click on FPSProject and select Build to compile your project.
If you are using the default setup of VS, you should have a dialogue box near the bottom of the program (likely below where you’ve been editing code). When you click Build, some dialogue should appear in that box while it processes, and it should then hopefully say it was built successfully. If the build failed, don’t stress! Just retrace your steps and make sure your code matches what we’ve listed here and in section 1.
-
After the build finishes, open Unreal Editor to verify that your newly compiled FPSCharacter class is visible in the Content Browser.
Extending your C++ FPS Character Class to Blueprints
Now is a good time to extend the C++ FPS Character class to Blueprints (like you did previously with the FPSProject Game Mode). Please feel free to go to our C++ and Blueprints reference page to learn more about extending C++ classes to Blueprints.
-
Right-click the FPSCharacter class to open the C++ Class Actions menu.
-
Click Create Blueprint class based on FPSCharacter to open the Add Blueprint Class dialog menu.
-
Name your new Blueprint Class
BP_FPSCharacter
and choose the Blueprints folder before clicking the Create Blueprint Class button. -
By now, you should have a newly created
BP_FPSCharacter
Blueprint Class located inside of the Blueprints folder. -
Make sure to save your
BP_FPSCharacter
Blueprint before closing the Blueprint Editor.
Setting the Default Pawn Class
Now that you have successfully extended our newly modified Game Mode to Blueprints, you will need to set your project to use BP_FPSCharacter
as the default Pawn in this step.
-
In the Edit menu, click on Project Settings.
-
Under the Project heading on the left side of the Project Settings tab, click on Maps & Modes.
-
Expand the Selected GameMode section, and select BP_FPSCharacter in the Default Pawn Class dropdown menu.
-
Close the Project Settings menu.
-
Click the Play button in the Level Editor Toolbar. "We are using FPSCharacter." should now be displayed in red text below "Hello World, this is FPSGameMode!" for five seconds in the upper left corner of the viewport.
If you are unable to move, you are using FPSCharacter as your Pawn correctly! Your new Character doesn't have any movement controls yet, so you will not be able to move around in the level.
- Before going to the next step, press the Escape key or click Stop in the Level Editor to exit Play in Editor (PIE) mode.
2.2 - Setting up Axis Mapping
In general, Axis Mappings enable mapping keyboard, mouse, and controller inputs to a "friendly name" that can later be bound to game behavior (such as movement). Axis Mappings are continuously polled, allowing for seamless movement transitions and smooth game behavior. Hardware axis (such as controller joysticks) provide degrees of input, rather than discrete input (for example, 1 pressed vs. 0 not pressed). While controller joystick input methods are effective at providing scalable movement input, Axis Mappings can also map common movement keys (like WASD or arrow keys) to continuously-polled game behavior.
If you want to learn more about Player Input before moving forward with this step, please refer to the Player Input and Pawns tutorial. During this step, you are going to get your new Character to move around the map by setting up the input axis mappings for the W, A, S, and D keys.
MoveForward Axis Mapping
-
In the Edit menu, click Project Settings.
-
Under the Engine heading on the left side of the Project Settings tab, click Input.
-
Under Bindings, click the plus sign next to Axis Mappings.
-
Click the arrow to the left of Axis Mappings.
-
Type "MoveForward" into the text field that appears, then click the arrow to the left of the text box to expand the axis binding options.
-
In the dropdown menu, select W from the Keyboard dropdown list.
-
Your input settings should now look like the following:
-
Click the plus sign next to MoveForward.
-
In the second dropdown menu, select S from the Keyboard dropdown list.
-
Type "-1" in the Scale field next to S.
-
Your input settings should now look like the following:
MoveRight Axis Mapping
-
Under Bindings, click on the plus sign next to Axis Mappings.
-
Type "MoveRight" into the text field that appears, then click the arrow to the left of the text box to expand the axis binding options.
-
In the dropdown menu, select D from the Keyboard dropdown list.
-
Your input settings should now look like the following:
-
Click on the plus sign next to MoveRight.
-
In the second dropdown menu, select A from the Keyboard dropdown list.
-
Type "-1" in the Scale field next to A.
-
Your input settings should now look like the following:
-
Now that you have set your MoveLeft and MoveRight Axis Mappings, go ahead and close the Project Settings menu.
2.3 - Implementing Character Movement Functions
In this step, we are going to set-up our Player Input Component and implement the following functions in the FPSCharacter class:
MoveForward
MoveRight
Movement Function Interfaces
Now that you have set-up Axis mappings for your FPSCharacter, you can switch to your project in VS.
- In
FPSCharacter.h
, add the following function declarations underSetupPlayerInputComponent
.
// Handles input for moving forward and backward.
UFUNCTION()
void MoveForward(float Value);
// Handles input for moving right and left.
UFUNCTION()
void MoveRight(float Value);
The UFUNCTION
macro (located above each of these functions) makes the engine aware of these functions so that they can be included in serialization and other engine functionality.
FPSCharacter.h
should now look like the following:
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "FPSCharacter.generated.h"
UCLASS()
class FPSPROJECT_API AFPSCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFPSCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick( float DeltaTime ) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// Handles input for moving forward and backward.
UFUNCTION()
void MoveForward(float Value);
// Handles input for moving right and left.
UFUNCTION()
void MoveRight(float Value);
};
Movement Function Implementations
In a typical FPS control scheme, the character's movement axes are relative to the camera. "Forward" movement means "the direction that the camera is pointing" and "right" means "to the right of the direction that the camera is pointing." You are going to use the PlayerController
to get the character's control rotation. Also, your MoveForward
function will ignore the pitch component of the control rotation and restrict your input to the XY plane so as to guarantee that your character will move along the ground while you are looking up or down.
- In
FPSCharacter.cpp
, add the following lines to theSetupPlayerInputComponent
function underSuper::SetupPlayerInputComponent(PlayerInputComponent);
.
// Set up "movement" bindings.
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
An InputComponent
is a component that defines how to handle input data. An InputComponent
can be attached to an actor that wants to receive input.
- Below
SetupPlayerInputComponent
, add the followingMoveForward
function definition inFPSCharacter.cpp
.
void AFPSCharacter::MoveForward(float Value)
{
// Find out which way is "forward" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
- Add the following
MoveRight
function definition inFPSCharacter.cpp
(belowMoveForward
).
void AFPSCharacter::MoveRight(float Value)
{
// Find out which way is "right" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);
}
FPSCharacter.cpp
should now look like the following:
// Copyright Epic Games, Inc. All Rights Reserved.
#include "FPSCharacter.h"
// Sets default values
AFPSCharacter::AFPSCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AFPSCharacter::BeginPlay()
{
Super::BeginPlay();
check(GEngine != nullptr);
// Put up a debug message for five seconds.
// The -1 "Key" value argument prevents the message from being updated or refreshed.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
}
// Called every frame
void AFPSCharacter::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
// Called to bind functionality to input
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Set up "movement" bindings.
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
}
void AFPSCharacter::MoveForward(float Value)
{
// Find out which way is "forward" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::MoveRight(float Value)
{
// Find out which way is "right" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);
}
Testing Character Movement
It is now time to compile and test your newly implemented character movement functions.
-
Save the
FPSCharacter
header (.h) and C++ (.cpp) files in VS. -
Locate FPSProject in the Solution Explorer.
-
Right-click on FPSProject and select Build to compile your project.
-
After the build finishes, open your FPSProject in the Unreal Editor.
-
Click Play in the Level Editor Toolbar. By now, you should be able to move forward, backward, left, and right.
-
Press the Escape key or click Stop in the Level Editor to exit PIE mode.
2.4 - Implementing Mouse Camera Control
During this step, you are going to add the ability for your character to look around and steer with the mouse.
Turn Axis Mapping
-
In your FPS project, expand the Edit menu and click Project Settings.
-
Under the Engine heading on the left side of the Project Settings tab, click Input.
-
Under Bindings, click the plus sign next to Axis Mappings.
-
Click the arrow to the left of Axis Mappings.
-
Type "Turn" into the text field that appears, then click the arrow to the left of the text box to expand the axis binding options
-
In the dropdown menu, select Mouse X from the Mouse dropdown list.
-
Your input settings should now look like the following:
Look-up Axis Mapping
-
Under Bindings, click the plus sign next to Axis Mappings.
-
Type "LookUp" into the text field that appears, then click the arrow to the left of the text box to expand the axis binding options.
-
In the dropdown menu, select Mouse Y from the Mouse dropdown list.
-
Type "-1.0" in the Scale field next to Mouse Y.
-
Your input settings should now look like the following:
-
Close the Project Settings menu.
Implementing Input Handling
Now it is time to add code to handle mouse input for turning and looking up. The Character
base class defines the two necessary functions for us, namely:
AddControllerYawInput
AddControllerPitchInput
If you want to perform additional processing, such as adding support for sensitivity or axis inversion, you could provide your own functions to adjust the input values before passing them to function. In this case however, you will bind your inputs directly to the AddControllerYawInput
and AddControllerPitchInput
functions.
- Add the following lines to the
SetupPlayerInputComponent
function inFPSCharacter.cpp
.
// Set up "look" bindings.
PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);
- The
SetupPlayerInputComponent
function should now look like the following:
// Called to bind functionality to input
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Set up "movement" bindings.
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
// Set up "look" bindings.
PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);
}
Testing Mouse Camera Control
-
Save the
FPSCharacter
implementation file in VS. -
Locate FPSProject in the Solution Explorer.
-
Right-click on FPSProject and select Build to compile your project.
-
After the build finishes, open your FPSProject in the Unreal Editor.
-
Click Play in the Level Editor Toolbar. You can now control the camera with your mouse.
-
Press the Escape key or click Stop in the Level Editor to exit PIE mode.
2.5 - Implementing Character Jumping
In general, Action Mappings deal with inputs for discrete events, they allow you to map inputs to a "friendly name" that can later be bound to event-driven behavior. The end effect is pressing and/or releasing a key, mouse button, or keypad button directly triggers game behavior. During this step, you are going to add the ability for your character to jump by setting up the input action mapping for the space bar.
Jump Action Mapping
-
In the Edit menu, click Project Settings.
-
Under the Engine heading on the left side of the Project Settings tab, click Input.
-
Under Bindings, click the plus sign next to Action Mappings.
-
Click the arrow to the left of Action Mappings.
-
Type "Jump" into the text field that appears, then click the arrow to the left of the text box to expand the action binding options.
-
In the dropdown menu, select Space Bar from the Keyboard dropdown list.
-
Your input settings should now look like the following:
-
Close the Project Settings menu.
Implement Input Handling
If you look inside the interface file (.h) for the ACharacter
base class, you will notice that there is built-in support for character jumping. Character jumping is tied to the bPressedJump
variable, so all we need to do is set that boolean to true
when the jump action is pressed, and false
when the jump action is released. You will need to add the following two functions to accomplish this:
StartJump
StopJump
Go back to Visual Studio to add code to your FPSCharacter
class.
- In
FPSCharacter.h
, add the following public function declarations:
// Sets jump flag when key is pressed.
UFUNCTION()
void StartJump();
// Clears jump flag when key is released.
UFUNCTION()
void StopJump();
FPSCharacter.h
should now look like the following:
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include “CoreMinimal.h”
#include "GameFramework/Character.h"
#include "FPSCharacter.generated.h"
UCLASS()
class FPSPROJECT_API AFPSCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFPSCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick( float DeltaTime ) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// Handles input for moving forward and backward.
UFUNCTION()
void MoveForward(float Value);
// Handles input for moving right and left.
UFUNCTION()
void MoveRight(float Value);
// Sets jump flag when key is pressed.
UFUNCTION()
void StartJump();
// Clears jump flag when key is released.
UFUNCTION()
void StopJump();
};
- In
FPSCharacter.cpp
, add the following function definitions to the bottom of the page:
void AFPSCharacter::StartJump()
{
bPressedJump = true;
}
void AFPSCharacter::StopJump()
{
bPressedJump = false;
}
- Now, add the following code to
SetupPlayerInputComponent
to bind your Jump action to the newly written functions:
// Set up "action" bindings.
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
FPSCharacter.cpp
should now look like the following:
// Copyright Epic Games, Inc. All Rights Reserved.
#include "FPSCharacter.h"
// Sets default values
AFPSCharacter::AFPSCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AFPSCharacter::BeginPlay()
{
Super::BeginPlay();
check(GEngine != nullptr);
// Display a debug message for five seconds.
// The -1 "Key" valueargument prevents the message from being updated or refreshed.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
}
// Called every frame
void AFPSCharacter::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
// Called to bind functionality to input
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Set up "movement" bindings.
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
// Set up "look" bindings.
PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);
// Set up "action" bindings.
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
}
void AFPSCharacter::MoveForward(float Value)
{
// Find out which way is "forward" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::MoveRight(float Value)
{
// Find out which way is "right" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::StartJump()
{
bPressedJump = true;
}
void AFPSCharacter::StopJump()
{
bPressedJump = false;
}
Testing Character Jumping
It is now time to compile and test your newly implemented character movement functions.
-
Save the FPSCharacter header (.h) and CPP (.cpp) files in VS.
-
Locate FPSProject in the Solution Explorer.
-
Right-click on FPSProject and select Build to compile your project.
-
After the build finishes, open your FPSProject in the Unreal Editor.
-
Click Play in the Level Editor Toolbar. You should be able to jump throughout the map.
-
Press the Escape key or click Stop in the Level Editor to exit PIE mode.
2.6 - Adding a Mesh to your Character
Download and extract the sample mesh from the following link:
During this step, you will give the character a skeletal mesh. The Character class creates a SkeletalMeshComponent object for you by default, so all it needs to know is which SkeletalMesh asset to use.
Importing a Skeletal Mesh
-
Navigate back to the Content folder inside of the Content Browser's file box.
-
Now, right-click inside the Content Browser's file box to open the Import Asset dialog box.
-
Click 'Import to /Game...' to open the Import dialog box.
-
Locate and select the GenericMale.fbx mesh file.
-
Click Open to begin importing the mesh to your project.
-
In the Content Browser, the FBX Import Options dialog box appears. Clicking Import All adds your mesh to the Project.
-
Click the Save button to save your imported mesh.
Setting up a Third Person Mesh
- Double-click the BP_FPSCharacter Blueprint Class icon in Content > Blueprints to open it in the Blueprint Editor.
If you see a note about this Blueprint being a data only blueprint, click Open Full Blueprint Editor.
-
Click the Mesh component in the Components tab.
-
Scroll to the Mesh section of the Details tab (right-side of screen, or under Window > Details).
-
Click the dropdown that reads "None" in the Skeletal Mesh row, and select the GenericMale skeletal mesh.
-
Scroll to the Transform section in the Details pane and align the
SkeletalMeshComponent
to theCapsuleComponent
by setting its Z Location to "-88.0". -
Open the Viewport to preview the Skeletal Mesh. It should look like the following:
Verify that the skeletal mesh is inside the CapsuleComponent
and that the mesh is facing the same direction as the ArrowComponent
. Properly orienting the skeletal mesh component will ensure that your character moves through the world in the right way.
- Make sure to Compile and Save the BP_FPSCharacter Blueprint before closing the Blueprint Editor.
Verifying the New Mesh in PIE Mode
It is now time to view your newly added mesh in-editor.
-
Click the Play button in the Level Editor Toolbar. You should be able to see your character's shadow as you move around.
If you want to see your character's mesh inside the editor's viewport, press the F8 key to eject yourself from your pawn. After pressing the F8 key, you'll be able to to move your camera freely through the level. To move your camera, hold the left mouse button down while moving the mouse at the same time.

- Press the Escape key or click the Stop button in the Level Editor to exit Play in Editor (PIE) mode.
2.7 - Changing the Camera View
At the end of the previous step, the default camera was positioned inside the mesh's neck. During this step, you're going to set-up an FPS camera that you can use to adjust the camera's properties (such as location and field of view).
Before you get started, you need to expand your list of included files in FPSCharacter.h
. This will allow your code to access more camera-related functions, and will ultimately allow you to manipulate your camera placement.
-
Open your Visual Studio project, and navigate to
FPSCharacter.h
. -
Include the following header files to
FPSCharacter.h
.
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
Attaching a Camera Component
- Open
FPSCharacter.h
to add the following code:
// FPS camera.
UPROPERTY(VisibleAnywhere)
UCameraComponent* FPSCameraComponent;
FPSCharacter.h
should now look like the following:
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "FPSCharacter.generated.h"
UCLASS()
class FPSPROJECT_API AFPSCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFPSCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick( float DeltaTime ) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// Handles input for moving forward and backward.
UFUNCTION()
void MoveForward(float Value);
// Handles input for moving right and left.
UFUNCTION()
void MoveRight(float Value);
// Sets jump flag when key is pressed.
UFUNCTION()
void StartJump();
// Clears jump flag when key is released.
UFUNCTION()
void StopJump();
// FPS camera
UPROPERTY(VisibleAnywhere)
UCameraComponent* FPSCameraComponent;
};
- Open
FPSCharacter.cpp
and add the following code to the constructor belowPrimaryActorTick.bCanEverTick = true:
.
// Create a first person camera component.
FPSCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
check(FPSCameraComponent != nullptr);
// Attach the camera component to our capsule component.
FPSCameraComponent->SetupAttachment(CastChecked<USceneComponent, UCapsuleComponent>(GetCapsuleComponent()));
This code creates a UCameraComponent
and attaches it to the character's CapsuleComponent
.
- Now, add the following code underneath the block that you just wrote in the constructor:
// Position the camera slightly above the eyes.
FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
// Enable the pawn to control camera rotation.
FPSCameraComponent->bUsePawnControlRotation = true;
This code adjusts the camera's position to be slightly above the character's eye position while allowing the pawn to control the camera's rotation.
SetRelativeLocation
sets the default for the component. However, the previous value will still be set in the Editor. To correct this, open the Blueprint Editor. Click the FPSCameraComponent
and in the Details panel locate the Transform -> Location value. Click the yellow Reset to Default icon next to that value.
FPSCharacter.cpp
should now look like the following:
// Copyright Epic Games, Inc. All Rights Reserved.
#include "FPSCharacter.h"
// Sets default values
AFPSCharacter::AFPSCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Create a first person camera component.
FPSCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
check(FPSCameraComponent != nullptr);
// Attach the camera component to our capsule component.
FPSCameraComponent->SetupAttachment(CastChecked<USceneComponent, UCapsuleComponent>(GetCapsuleComponent()));
// Position the camera slightly above the eyes.
FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
// Enable the pawn to control camera rotation.
FPSCameraComponent->bUsePawnControlRotation = true;
}
// Called when the game starts or when spawned
void AFPSCharacter::BeginPlay()
{
Super::BeginPlay();
check(GEngine != nullptr)
// Display a debug message for five seconds.
// The -1 "Key" value (first argument) indicates that we will never need to update or refresh this message.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
}
// Called every frame
void AFPSCharacter::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
// Called to bind functionality to input
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Set up "movement" bindings.
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
// Set up "look" bindings.
PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);
// Set up "action" bindings.
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
}
void AFPSCharacter::MoveForward(float Value)
{
// Find out which way is "forward" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::MoveRight(float Value)
{
// Find out which way is "right" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::StartJump()
{
bPressedJump = true;
}
void AFPSCharacter::StopJump()
{
bPressedJump = false;
}
Testing the New Camera
It is now time to compile and test your newly implemented camera code.
-
Save the
FPSCharacter
header (.h) and CPP (.cpp) files in Visual Studio. -
Locate FPSProject in the Solution Explorer.
-
Right-click on FPSProject and select Build to compile your project.
-
After the build finishes, open your FPSProject in the Unreal Editor.
-
Click Play in the Level Editor Toolbar.
The camera should now be slightly above your character's head.
You can also verify your newly added camera component by opening the BP_FPSCharacter Viewport.

2.8 - Add a First Person Mesh to your Character
A common approach for building FPS games is to use two separate character meshes where one is the full-body mesh and the other is the "weapon and hands" mesh. The full-body mesh is used to see the character from a third-person perspective; however, it is hidden when the player is viewing the game in first-person perspective. The "weapon and hands" mesh is typically attached to the camera and is only visible to the player when they are viewing the map in first-person perspective. During this step, you are going to add a first person mesh to your character.
Adding the First Person Character Mesh
- Switch back to Visual Studio and open
FPSCharacter.h
to add the following code under public:
// First-person mesh (arms), visible only to the owning player.
UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
USkeletalMeshComponent* FPSMesh;
- Now, open
FPSCharacter.cpp
, go to the constructor, and add the following code to create and configure the first person mesh:
// Create a first person mesh component for the owning player.
FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
check(FPSMesh != nullptr);
// Only the owning player sees this mesh.
FPSMesh->SetOnlyOwnerSee(true);
// Attach the FPS mesh to the FPS camera.
FPSMesh->SetupAttachment(FPSCameraComponent);
// Disable some environmental shadows to preserve the illusion of having a single mesh.
FPSMesh->bCastDynamicShadow = false;
FPSMesh->CastShadow = false;
SetOnlyOwnerSee
indicates that this mesh is only visible to the PlayerController
that has possessed this Character. This code is also attaching the mesh to the camera and disabling some environmental shadowing. Allowing the arms to cast shadows would destroy the illusion of having a single mesh for the first person character.
- Finally, add the following code to the constructor in FPSCharacter.cpp to hide the existing third-person mesh from the owning character:
// The owning player doesn't see the regular (third-person) body mesh.
GetMesh()->SetOwnerNoSee(true);
-
Save the FPSCharacter header (.h) and implementation (.cpp) files in Visual Studio.
-
Locate FPSProject in the Solution Explorer.
-
Right-click on FPSProject and select Build to compile your project.
-
After the build finishes, open and run your FPSProject in PIE mode.
At this point, your character mesh should not be visible inside the editor.
If you still see your mesh and its shadow cast, close and restart the editor.
Building the Mesh Blueprint
Before continuing, download and extract the sample mesh from the following link: "First Person Skeletal Mesh"
-
Right-click inside the Content Browser's file box to open the Import Asset dialog box.
-
Click Import to /Game... to open the Import dialog box.
-
Locate and select the HeroFPP.fbx mesh file.
-
Click Open to begin importing the mesh to your project.
-
In the Content Browser, the FBX Import Options dialog box appears.
-
Verify that Skeleton is set to None before clicking Import All.
-
Close the following message log.
This mesh still shows the first person mesh set-up and it will work with the animations you'll set-up in a later section.
-
Click Save to save your imported mesh.
-
Navigate back to the Blueprints folder in the Content Browser.
-
Double-click the BP_FPSCharacter icon to open it in the Blueprint Editor.
-
Locate the new FPSMesh component in the Components tab. You may need to open the Full Blueprint Editor first.
The FPSMesh component is a child of the FPSCameraComponent, which means that it will always be attached to the camera.
-
Click the FPSMesh in the Components menu.
-
Scroll to the Mesh section of the Details tab and click the dropdown menu that says "None". Now, select the HeroFPP skeletal mesh to add the arms to the Viewport.
-
The newly added HeroFPP skeletal mesh should look like the following inside the Viewport.
-
Adjust the newly added mesh's transform to be in front of the camera by setting its Location to {220, 0, 35} and by setting its Rotation to {180, 50, 180}.
Click on the image to zoom in.
- Make sure to Compile and Save the BP_FPSCharacter Blueprint before closing the Blueprint Editor.
Viewing the New Mesh In-Game
-
Click the Play button in the Level Editor Toolbar to view the new mesh in-game.
-
Press the Escape key or click the Stop button in the Level Editor to exit Play in Editor (PIE) mode.
Finished Section Code
FPSCharacter.h
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/Character.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "FPSCharacter.generated.h"
UCLASS()
class FPSPROJECT_API AFPSCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFPSCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick( float DeltaTime ) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// Handles input for moving forward and backward.
UFUNCTION()
void MoveForward(float Value);
// Handles input for moving right and left.
UFUNCTION()
void MoveRight(float Value);
// Sets jump flag when key is pressed.
UFUNCTION()
void StartJump();
// Clears jump flag when key is released.
UFUNCTION()
void StopJump();
// FPS camera
UPROPERTY(VisibleAnywhere)
UCameraComponent* FPSCameraComponent;
// First-person mesh (arms), visible only to the owning player.
UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
USkeletalMeshComponent* FPSMesh;
};
FPSCharacter.cpp
// Copyright Epic Games, Inc. All Rights Reserved.
#include "FPSCharacter.h"
// Sets default values
AFPSCharacter::AFPSCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Create a first person camera component.
FPSCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
check(FPSCameraComponent != nullptr);
// Attach the camera component to our capsule component.
FPSCameraComponent->SetupAttachment(CastChecked<USceneComponent>(GetCapsuleComponent()));
// Position the camera slightly above the eyes.
FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
// Enable the pawn to control camera rotation.
FPSCameraComponent->bUsePawnControlRotation = true;
// Create a first person mesh component for the owning player.
FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
check(FPSMesh != nullptr);
// Only the owning player sees this mesh.
FPSMesh->SetOnlyOwnerSee(true);
// Attach the FPS mesh to the FPS camera.
FPSMesh->SetupAttachment(FPSCameraComponent);
// Disable some environmental shadowing to preserve the illusion of having a single mesh.
FPSMesh->bCastDynamicShadow = false;
FPSMesh->CastShadow = false;
// The owning player doesn't see the regular (third-person) body mesh.
GetMesh()->SetOwnerNoSee(true);
}
// Called when the game starts or when spawned
void AFPSCharacter::BeginPlay()
{
Super::BeginPlay();
check(GEngine != nullptr);
// Display a debug message for five seconds.
// The -1 "Key" value argument prevents the message from being updated or refreshed.
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter."));
}
// Called every frame
void AFPSCharacter::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
// Called to bind functionality to input
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// Set up "movement" bindings.
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
// Set up "look" bindings.
PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);
// Set up "action" bindings.
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
}
void AFPSCharacter::MoveForward(float Value)
{
// Find out which way is "forward" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::MoveRight(float Value)
{
// Find out which way is "right" and record that the player wants to move that way.
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, Value);
}
void AFPSCharacter::StartJump()
{
bPressedJump = true;
}
void AFPSCharacter::StopJump()
{
bPressedJump = false;
}
Congratulations! You've learned how to:
✓ Make a New Character ✓ Set-up Axis Mapping ✓ Implement Character Movement Functions ✓ Implement Mouse Camera Control ✓ Implement Character Jumping ✓ Add a Mesh to your Character ✓ Change the Camera View ✓ Add a First Person Mesh to your Character
You're now ready to learn how to implement projectiles in the next section.