As I said last week, I have started a top down arena brawler. I made this decision when I was in Perrenporth Cornwall, with no internet access. Probably not the wisest time to start a game with an engine you don’t know.
Well I say I don’t know I did start a project with some friends, a 2.5d brawler taking inspiration from Super Smash Bro.
Like other most part time projects done with friends it didn’t go anywhere, even though we spent a lot of time modifying UE physics to work with the game concept. Anyhow this was almost five years ago so any knowledge I had about UE has pretty much disappeared.
For this brawl game I started with the Top down project template. This sets up a top down character and small test area. When the project is run you can move the player character by clicking in the environment where you want the player actor to move to. I am also using Paragon SunWukong character which is free on the Unreal asset store.
This was a good start, so I deleted all the code relating to mouse input since it’s not needed for this project. I needed the player character to move with a controller thumb stick.
So how is this done? Well you need to bind the input of the thumb stick to two methods, when you move the stick the methods are called with a value that represents the amount the stick has moved.
To do this open Edit->Project Settings.

Find engine input, and clear out any current mappings. Add two new mappings, call the first one “ForwardsBackwards” and the second “LeftRight”. Under ForwadsBackwards bind that to “Gamepad Left Thumbstick Y-axis”. Under “LeftRight” bind “Gamepad Left ThumbStick X-Axis” both scale values should be 1.0. This is important because moving the thumb stick all the way forward will give up a value of 1.0, and all the way back –1.0. The same for left and right.

Open up the visual studio project and find PlayerController. For me this was BrawlPlayerController.h and .cpp. Clear out any old input code. The header file should end up looking as follows
UCLASS()
class ABrawlPlayerController : public APlayerController
{
GENERATED_BODY()
public:
ABrawlPlayerController();
protected:
// Begin PlayerController interface
virtual void PlayerTick(float DeltaTime) override;
virtual void SetupInputComponent() override;
// End PlayerController interface
void OnForwardBackwards(float AxisValue);
void OnLeftRight(float AxisValue);
};
There are two new methods in here called “void OnForwardBackwards(float AxisValue);” and “void OnLeftRight(float AxisValue);”. These are important as whenever the thumb stick is moved these methods will be called.
Next we need to edit the .cpp file so open this up. Modify the code so it looks like below.
#include "BrawlPlayerController.h"
#include "Blueprint/AIBlueprintHelperLibrary.h"
#include "Runtime/Engine/Classes/Components/DecalComponent.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "BrawlCharacter.h"
#include "Engine/World.h"
ABrawlPlayerController::ABrawlPlayerController()
{
bShowMouseCursor = true;
}
void ABrawlPlayerController::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
APawn* const MyPawn = GetPawn();
if (MyPawn)
{
// Convert input values into a direction (the direction the thumb stick is pointing in)
const float ForwardValue = InputComponent->GetAxisValue("ForwardBackwards");
const float RightValue = InputComponent->GetAxisValue("LeftRight");
FVector MoveDirection = FVector(ForwardValue, RightValue, 0.0f);
MoveDirection.Normalize();
// If stick has moved convert direction into a rotation and apply to the actor
if (MoveDirection.SizeSquared() > 0.0f)
{
const FRotator NewRotation = MoveDirection.Rotation();
MyPawn->GetRootComponent()->MoveComponent(FVector(0.0f,0.0f,0.0f), NewRotation, true);
}
}
}
void ABrawlPlayerController::SetupInputComponent()
{
// set up gameplay key bindings
Super::SetupInputComponent();
InputComponent->BindAxis("ForwardBackwards", this, &ABrawlPlayerController::OnForwardBackwards);
InputComponent->BindAxis("LeftRight", this, &ABrawlPlayerController::OnLeftRight);
}
void ABrawlPlayerController::OnForwardBackwards(float AxisValue)
{
APawn* const MyPawn = GetPawn();
if (MyPawn)
{
MyPawn->AddMovementInput(FVector(1.0f, 0.0f, 0.0f), AxisValue);
}
}
void ABrawlPlayerController::OnLeftRight(float AxisValue)
{
APawn* const MyPawn = GetPawn();
if (MyPawn)
{
MyPawn->AddMovementInput(FVector(0.0f, 1.0f, 0.0f), AxisValue);
}
}
The important bits here are in “void ABrawlPlayerController::SetupInputComponent()” and “void ABrawlPlayerController::PlayerTick(float DeltaTime)”
Inside of SetupInputComponent we have BindAxis, it is these commands that tie together the controller input to calling the OnForwardsBackwards etc methods.
Inside these methods we call AddMovementInput, this takes the movement direction and the speed in which it is to move, this is provided by AxisValue. So in the case of “OnLeftRight” a + value will move the actor right and a – value left.
Now we come to turning the actor to face the direction of movement. I have to admit I struggled with this. (This is where the internet would have come in use). However, after playing about it was achieved as below.
First we need to put our input values as a direction. We do this by grabbing the Axis values “GetAxisValue”. This is then fed into a vector called “MovementDirection”, we normalize this to make sure its range is valid (it should be but its better to be safe than sorry).
We pull the rotation out of the vector “const FRotator NewRotation = MoveDirection.Rotation();” And then feed this into “MyPawn->GetRootComponent()->MoveComponent”
The first parameter is left blank as there is no delta we just want to turn the actor in this case.
Anyhow that’s it. I am 100% certain there is a much better way to do this. Probably within the blueprint system, but I want to do the majority of this with C++ since after all I am a gameplay programmer.
If there is a better way to do this in C++ please let me know.
And that’s it for this week, it needs some polish but that will come on another day. Next week we will look at some of my other projects and maybe how I am creating the arena since I am not an artist.
A tip that help me long, use UE_LOG to output real-time data. Break points are good but I find a real-time output much more informative.
Hope this helps 😊
