Hi all! I’ve been working on a small project of mine that require the use precise gamepad inputs. After some researches I’ve found this post that explain how to remap inputs to a perfect circle, which is quite ideal to me.
For now I made these changes in my player class and it work fine, but I’ve learned that it would be better to apply all these changes the closer to the source as possible. In this post they talked about creating a custom Player Controller and custom Player Input that will be responsible to manipulate the raw values of the axis and return the adjusted values. However, while following the instruction provided in that post, my code doesn’t work.
TLOZ_PlayerController.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "TLOZ_PlayerController.generated.h"
UCLASS()
class TLOZ_API ATLOZ_PlayerController : public APlayerController
{
GENERATED_BODY()
public:
ATLOZ_PlayerController();
void InitInputSystem() override;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "CustomInput")
float Deadzone;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "CustomInput")
float MagnitudeThreashold;
};
TLOZ_PlayerController.cpp
#include "CustomComponents/Controller/Player/TLOZ_PlayerController.h"
#include "CustomComponents/Controller/Player/TLOZ_PlayerInput.h"
#include "Characters/TLOZ_Character.h"
#include "CustomComponents/TLOZ_CharacterMovementComponent.h"
ATLOZ_PlayerController::ATLOZ_PlayerController()
: Deadzone(0.25f)
, MagnitudeThreashold(0.93f)
{}
void ATLOZ_PlayerController::InitInputSystem()
{
UTLOZ_PlayerInput* CustomPlayerInput = NewObject<UTLOZ_PlayerInput>(this);
CustomPlayerInput->Deadzone = Deadzone;
CustomPlayerInput->MagnitudeThreashold = MagnitudeThreashold;
PlayerInput = CustomPlayerInput;
APlayerController::InitInputSystem();
}
TLOZ_PlayerInput.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerInput.h"
#include "TLOZ_PlayerInput.generated.h"
UCLASS()
class TLOZ_API UTLOZ_PlayerInput : public UPlayerInput
{
GENERATED_BODY()
public:
virtual FVector MassageVectorAxisInput(FKey Key, FVector RawValue) override;
float MagnitudeThreashold;
float Deadzone;
};
TLOZ_PlayerInput.cpp
#include "CustomComponents/Controller/Player/TLOZ_PlayerInput.h"
FVector UTLOZ_PlayerInput::MassageVectorAxisInput(FKey Key, FVector RawValue)
{
// Get default Massaged Vector Axis Input
FVector LocRawValues = Super::MassageVectorAxisInput(Key, RawValue);
GEngine->AddOnScreenDebugMessage(11, 0.0f, FColor::Red, LocRawValues.ToString());
// Calculate magnitude
// Right now the value can be greater than 1 but we want to "normalize" it
float Magnitude = LocRawValues.Size();
Magnitude = (Magnitude > MagnitudeThreashold) ? 1 : Magnitude;
// Calculate ActiveRange (useful only for gamepad)
// ActiveRange is 0 when the gamepad magnitude is under the Deadzone, otherwise just return its value
float ActiveRange = (Magnitude - Deadzone) / (1 - Deadzone);
ActiveRange = (ActiveRange < 0) ? 0 : ActiveRange;
// Atan2 return the angle between to vectors
float Angle = FMath::Atan2(LocRawValues.Y, LocRawValues.X);
// Override axis values with the remapped values
const float NewAxisX = cos(Angle) * ActiveRange;
const float NewAxisY = sin(Angle) * ActiveRange;
GEngine->AddOnScreenDebugMessage(12, 0.0f, FColor::Red, FVector(NewAxisX, NewAxisY, LocRawValues.Z).ToString());
return FVector(NewAxisX, NewAxisY, LocRawValues.Z);
}
I’ve created a Blueprint out of the C++ TLOZ_PlayerController class and set the default Player Controller in my Game Mode to it. However, MassageVectorAxisInput is never called, thus, the axis values are never adjusted. What am I doing wrong? Thanks in advance for you attention.