I am a beginner in UE5 (I started learning yesterday), and I am now working on a simple task. It takes the WSAD and mouse to do simple movement and camera operations using input mapping context.
However, after my self-learning, I end up with this:
UCLASS()
class ASSIGNMENT1_API AFirstPersonCharactor : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AFirstPersonCharactor();
UPROPERTY(EditAnywhere, Category = "Components|Camera")
UCameraComponent* camera;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction *IA_KB_CM_InOut;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction* IA_KB_CM_LeftRight;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction* IA_KB_CL_UpDown;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
UInputAction* IA_KB_CL_LeftRight;
UPROPERTY(EditAnywhere, Category = "Input|Actions")
TSoftObjectPtr<UInputMappingContext> IMCControls;
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;
void KB_CM_InOut(const FInputActionInstance& Instance);
void KB_CM_LeftRight(const FInputActionInstance& Instance);
void KB_CL_UpDown(const FInputActionInstance& Instance);
void KB_CL_LeftRight(const FInputActionInstance& Instance);
};
and this is my cpp file:
// Sets default values
AFirstPersonCharactor::AFirstPersonCharactor()
{
PrimaryActorTick.bCanEverTick = true;
camera = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera"));
camera->SetupAttachment(RootComponent);
camera->SetRelativeLocation(FVector(0));
}
void AFirstPersonCharactor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AFirstPersonCharactor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AFirstPersonCharactor::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(GetController()))
{
if (UEnhancedInputLocalPlayerSubsystem* InputSystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
{
InputSystem->AddMappingContext(IMCControls.LoadSynchronous(),10);
}
}
UEnhancedInputComponent* input = Cast<UEnhancedInputComponent>(PlayerInputComponent);
if (IA_KB_CM_InOut) {
input->BindAction(IA_KB_CM_InOut, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CM_InOut);
}
if (IA_KB_CM_LeftRight) {
input->BindAction(IA_KB_CM_LeftRight, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CM_LeftRight);
}
if (IA_KB_CL_UpDown) {
input->BindAction(IA_KB_CL_UpDown, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CL_UpDown);
}
if (IA_KB_CL_LeftRight) {
input->BindAction(IA_KB_CL_LeftRight, ETriggerEvent::Started, this, &AFirstPersonCharactor::KB_CL_LeftRight);
}
}
void AFirstPersonCharactor::KB_CM_InOut(const FInputActionInstance &Instance)
{
printf("a");
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddMovementInput(GetActorForwardVector(),FloatValue);
}
}
void AFirstPersonCharactor::KB_CM_LeftRight(const FInputActionInstance& Instance)
{
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddMovementInput(GetActorRightVector(), FloatValue);
}
}
void AFirstPersonCharactor::KB_CL_LeftRight(const FInputActionInstance& Instance)
{
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddControllerYawInput(FloatValue);
}
}
void AFirstPersonCharactor::KB_CL_UpDown(const FInputActionInstance& Instance)
{
float FloatValue = Instance.GetValue().Get<float>();
if (FloatValue != 0) {
AddControllerPitchInput(FloatValue);
}
}
This ends with no bug, and I have the inputAction
and inputMappingContext
assets set in the outliner. But no matter which key I press, there are always no behaviours I can observe.
EDIT: after I add GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("haha"));
to debug, I found that my SetupPlayerInputComponent
is working, but
if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(GetController()))
probably not.
You shouldn't be trying to cast your controller to local player, and also you'd rather setup MappingContext
in BeginPlay()
rather than in SetupInputComponent(...)
.
So instead of doing that cast and then trying to add mapping context do this:
if (auto PlayerController = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}