Language:
Page Info
Skill Level:
Engine Version:

2.8 - Add a First Person Mesh to your Character

Choose your OS:

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's 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're viewing the map in first-person perspective. During this step, we're going to add a first person mesh to our character.

Adding the First Person Character Mesh

  1. Switch back to Visual Studio and open FPSCharacter.h to add the following code:

    // First-person mesh (arms), visible only to the owning player.
    UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
    USkeletalMeshComponent* FPSMesh;
  2. Now, open FPSCharacter.cpp, go 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"));
    // 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;

    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 the camera-attahed arms to cast shadows would destroy the illusion of having a single mesh for the first person character.

  3. 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);
  4. Save the FPSCharacter header (*.h) and implementation (*.cpp) files in Visual Studio.

  5. Locate FPSProject in the Solution Explorer.

  6. Right-click on FPSProject and select Build to compile your project.

    BuildProject.png

  7. After the build finishes, open and run your FPSProject in PIE mode.

    HiddenMeshInGame.png

    At this point, your character mesh should not be visible inside the editor.

Building the Mesh Blueprint

Before continuing, download and extract our sample mesh from the following link: "First Person Skeletal Mesh"

  1. Right-click inside the Content Browser's file box to open the Import Asset dialog box

  2. Click 'Import to /Game...' to open the Import dialog box.

    RightClickImport.png

  3. Locate and select the HeroFPP.fbx mesh file.

  4. Click Open to begin importing the mesh to your project.

  5. In the Content Browser, the FBX Import Options dialog box appears. Clicking Import adds your mesh to the Project.

    Disregard the following error regarding smoothing groups: FBXWarning.png
    This mesh still illustrates the first person mesh set-up and it will work with the animations you'll set-up in a later section.

  6. Click the Save button to save your imported mesh.

  7. Navigate back to the Blueprints folder in the Content Browser.

  8. Double-click the BP_FPSCharacter icon to open it in the Blueprint Editor.

  9. Locate the new FPSMesh component in the Components tab.

    LocateFPSMeshComponent.png

    The FirstPersonMesh component is a child of the FirstPersonCameraComponent, which means that it will always be attached to the camera.

  10. Click on the FirstPersonMesh in the Components menu.

  11. Scroll down to the Mesh section of the Details tab and click on the dropdown menu that says "None". Now, select the HeroFPP skeletal mesh to add the arms to the Viewport.

    SelectHeroFPPSkeletalMesh.png

  12. The newly added HeroFPP skeletal mesh should look like the following inside the Viewport.

    HeroFPPMesh_Viewport.png

  13. Adjust the newly added mesh's transform to be in front of the camera by setting its Location to {240, 0, 35} and by setting its Rotation to {-180, 50, -180}.

    Click on the image to zoom in.

  14. Make sure to Compile and Save the BP_FPSCharacter Blueprint before closing the Blueprint Editor.

Viewing the New Mesh In-Game

  1. Click the Play button in the Level Editor Toolbar to view the new mesh in-game.

    NewMeshInGame.png

  2. 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

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#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 DeltaSeconds ) 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

// Fill out your copyright notice in the Description page of Project Settings.

#include "FPSProject.h"
#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"));
    // Attach the camera component to our capsule component.
    FPSCameraComponent->SetupAttachment(GetCapsuleComponent());
    // Position the camera slightly above the eyes.
    FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight));
    // Allow the pawn to control camera rotation.
    FPSCameraComponent->bUsePawnControlRotation = true;

    // Create a first person mesh component for the owning player.
    FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
    // 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();

    if (GEngine)
    {
        // Put up 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(class 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.