How to make Character movement more adequate

Ok so basically, I’m working on the FPS tutorial that exists on UE4 programming tutorials. Besides all the hardships that I’ve gone through because of the tutorial being outdated, I noticed that the character movement is neat, but something bothered me a bit. In the tutorial, the forward movement of the character is based on getting the controller rotation, and then getting its X scaled axis.

FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);

and then the tutorial gives AddMovementInput the Direction and that’s basically it.

AddMovementInput(Direction, Value);

Now the thing that bothers me is that the movement speed changes by which angle I look at horizontally, so for example, if I look straight down or up, I won’t be able to move forward or backwards, and the more I look straight forward, the faster I move.
I’ve managed to come up with a pretty primitive solution, and that is by getting FPSMesh's* direction and adding it to the current Direction, all that while multiplying Direction by 2.

AddMovementInput(Direction*2+NewDirection, Value);

*FPSMesh is the Skeleton of the character

I first tried adding only the direction of the Skeleton, and that would’ve solved my problem, since when I look down or up my movement speed doesn’t change, but for some odd reason, when I try to move forward I move backwards and vice versa.(Note : Moving forward/Backwards using this method is also slower than usual.)

Now this almost solves my problem, but it just doesn’t seem right to me, and I was hoping that maybe one of you guys could offer me a more appropriate solution to this problem. Thanks.

Inserting the entirety of CPP file and H for anyone who wants to dig deeper:

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Camera/CameraComponent.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;
	//Adds Camera to edit
	UPROPERTY(EditAnywhere)
	    UCameraComponent* FPSCameraComponent;
	//Adds Body component
	UPROPERTY(VisibleAnywhere, Category = "Mesh")
		USkeletalMeshComponent* FPSMesh;
	// 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();
	//Shoots out FPSProjectile.
	UFUNCTION()
		void Fire();
	// Gun muzzle's offset from the camera location.
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
		FVector MuzzleOffset;
	// Projectile class to spawn.
	UPROPERTY(EditDefaultsOnly, Category = Projectile)
		TSubclassOf<class AFPSProjectile> ProjectileClass;

};

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

#include "FPSCharacter.h"
#include "FPSProjectile.h"
#include "Engine.h"
// Sets default values
AFPSCharacter::AFPSCharacter()
{
	//CONFIGURATION OF RELATIVITY
 	// 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 default mesh for our body
	FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh"));
	//Attaching the camera to the body
	FPSMesh->SetupAttachment(FPSCameraComponent);
}

// Called when the game starts or when spawned
void AFPSCharacter::BeginPlay()
{
	Super::BeginPlay();
	//Disabling some enviromental effects to preserve the illusion of having a singular mesh; NOTE::ENVIROMENTAL CHANGES CAN ONLY BE APPLIED IN THE BEGINNING OF THE SCENE, AND NOT IN THE CONFIGURATION.
	FPSMesh->SetCastShadow(false);
	// The owning player doesn't see the regular (third-person) body mesh.
	GetMesh()->SetOwnerNoSee(true);
	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::Yellow, 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 jumping
	PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
	PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);
	//Set up Firing
	PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCharacter::Fire);
}
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);
	FVector NewDirection = FRotationMatrix(FPSMesh->GetComponentRotation()).GetScaledAxis(EAxis::X);
	AddMovementInput(Direction*2+NewDirection, Value); //Works better than Direction/NewDirection alone.
	//AddMovementInput(CameraDirection, Value); //Same result as Direction.
}
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;
}
void AFPSCharacter::Fire()
{
	// Attempt to fire a projectile.
	if (ProjectileClass)
	{
		// Get the camera transform.
		FVector CameraLocation;
		FRotator CameraRotation;
		GetActorEyesViewPoint(CameraLocation, CameraRotation);

		// Transform MuzzleOffset from camera space to world space.
		FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset);
		FRotator MuzzleRotation = CameraRotation;
		// Skew the aim to be slightly upwards.
		MuzzleRotation.Pitch += 10.0f;
		UWorld* World = GetWorld();
		if (World)
		{
			FActorSpawnParameters SpawnParams;
			SpawnParams.Owner = this;
			SpawnParams.Instigator = Instigator;
			// Spawn the projectile at the muzzle.
			AFPSProjectile* Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);
			if (Projectile)
			{
				// Set the projectile's initial trajectory.
				FVector LaunchDirection = MuzzleRotation.Vector();
				Projectile->FireInDirection(LaunchDirection);
			}
		}
	}
}