Handling input on a per pawn basis in C++

So I’m just starting out with using C++ in UE4 and am trying to make my own character inheriting from the Character class. It compiles fine, but crashes when I hit the play button, and throws me an error saying “Access Violation”.

I’ve been googling for the past 2 hours reading several UE4 AnswerHub questions, but none seem to apply for what I want. They are all telling me to bind my inputs in the PlayerController, but then how am I supposed to use the actual inputs on a per pawn basis (For example different types of characters, one that can fly but another which can’t etc.)

I did get it working in Blueprint before but then decided to use C++ as I prefer programming over visual scripting (faster to type than keep clicking everywhere, and is more clear compared to a load of lines everywhere)

Here’s my code (the axis used are defined in the project settings):

NovaPlayer.h

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

#pragma once

#include "GameFramework/Character.h"
#include "NovaPlayer.generated.h"

/**
 *
 */

UCLASS()
class PROJECTNOVATERRA_API ANovaPlayer : public ACharacter
{
	GENERATED_UCLASS_BODY()

	bool isSprinting;

public:

	void ANovaPlayer::BeginPlay() override;

	void MoveForward(float axisValue);

	void MoveRight(float axisValue);

	void LookUp(float axisValue);

	void LookRight(float axisValue);

	void Sprint(float axisValue);
};

NovaPlayer.cpp

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

#include "ProjectNovaTerra.h"
#include "NovaPlayer.h"

ANovaPlayer::ANovaPlayer(const FObjectInitializer& init)
: Super(init) {
}

void ANovaPlayer::BeginPlay() {
	InputComponent->BindAxis("MoveForward", this, &ANovaPlayer::MoveForward);
	InputComponent->BindAxis("MoveRight", this, &ANovaPlayer::MoveRight);
	InputComponent->BindAxis("LookUp", this, &ANovaPlayer::LookUp);
	InputComponent->BindAxis("LookRight", this, &ANovaPlayer::LookRight);
	InputComponent->BindAxis("Sprint", this, &ANovaPlayer::Sprint);
}

void ANovaPlayer::MoveForward(float axisValue) {
	AddMovementInput(GetActorForwardVector(), isSprinting ? 1 : 0.5f);
}

void ANovaPlayer::MoveRight(float axisValue) {
	AddMovementInput(GetActorRightVector(), isSprinting ? 1 : 0.5f);
}

void ANovaPlayer::LookUp(float axisValue) {
	float preClampedPitch = GetActorRotation().Pitch + axisValue;

	AddControllerPitchInput(FMath::ClampAngle(preClampedPitch, -90, 90));
}

void ANovaPlayer::LookRight(float axisValue) {
	AddControllerYawInput(axisValue);
}

void ANovaPlayer::Sprint(float axisValue) {
	isSprinting = axisValue > 0 ? true : false;
}

Sidenote: I’ve never actually used C++ in any other project before, but I believe that I understand it fairly well. So if there’s any beginner errors in my code please do point them out!

I find this line weird :

void ANovaPlayer::BeginPlay() override;

I think it should be:

virtual void BeginPlay() override;

Maybe this is not the issue, but give it a try. Also, if it still happens, post the Log of when your access violation pops up. It can often help in determining the problem. It should be in YourGame/Saved/Logs.

Mick

Is this what you were asking for? http://pastebin.com/5CC1ssq9

Yes. From what I can see, I would say that at the moment of your binding, the InputComponent is not yet created.

In Character, there is a specific function where you should do your binding. If I remember correctly, it is SetupPlayerInputComponent(). So, instead of doing the binding in BeginPlay() you should do in in that function by overriding it.

Basically, in your .h :

virtual void SetupPlayerInputComponent(UInputComponent* InputComponent) override;

In your cpp:

void ANovaPlayer::SetupPlayerInputComponent(UInputComponent* InputComponent)
{
     check(InputComponent);
     InputComponent->BindAxis("MoveForward", this, &ANovaPlayer::MoveForward);
     InputComponent->BindAxis("MoveRight", this, &ANovaPlayer::MoveRight);
     InputComponent->BindAxis("LookUp", this, &ANovaPlayer::LookUp);
     InputComponent->BindAxis("LookRight", this, &ANovaPlayer::LookRight);
     InputComponent->BindAxis("Sprint", this, &ANovaPlayer::Sprint);
}

That did seem to be the issue, thanks! Does “check(InputComponent);” check if it’s null? Also, could you turn this into an answer so I can accept it? :slight_smile:

You can reply to yourself and accept that as answer. Don’t forget to give credit to where it is due.