I just cant get my pawn to move (c++)

I have tried a lot of different things. I have a pawn c++, I have a pawnmovementcomponent in c++, I have (I think correctly?) assigned the pawnmovementcomponent to the pawn. I have tested the component by in the tick printing a debug message and it works fine. I also have the mouse controlling the camera working fine, but that code is in the pawn. For some reason, I cant do anything with movement. ‘addmovementinput()’ doesnt work, ‘setting velocity of move comp’ doesnt work, I cant even set the location. It’s just constantly stuck, and doesnt move.

This is part of my pawnmovementcomponent.h

class ADellPawn;

/**
 * 
 */
UCLASS()
class DELLMOD_API UDellPawnMoveComp : public UPawnMovementComponent
{
	GENERATED_BODY()

public: 
	/** Character this belongs to */
	ADellPawn* Player;

This is part of my pawns.h

class UDellPawnMoveComp;

// ..... just the regular header code.... but including this...

/** Called when the character changes controller or gets a new one */
	virtual void PossessedBy(AController* NewController);

	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;

	AController* Controller;

public:

	/** Character's movement component */
	UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
		UDellPawnMoveComp* MovementComponent;

this is part of my pawns.cpp

 // Called to bind functionality to input
    void ADellPawn::SetupPlayerInputComponent(UInputComponent* InputComponent)
    {
    	Super::SetupPlayerInputComponent(InputComponent);
    
    	check(InputComponent);
    
    	// Set up movement
    	InputComponent->BindAxis("ForwardMovement", this, &ADellPawn::MoveForward);
    	InputComponent->BindAxis("RightMovement", this, &ADellPawn::MoveRight);
    
    	InputComponent->BindAction("Jump", IE_Pressed, this, &ADellPawn::StartJump);
    	InputComponent->BindAction("Jump", IE_Released, this, &ADellPawn::StopJump);
    
    	// Set up mouse inputs
    	InputComponent->BindAxis("MouseControlX", this, &ADellPawn::MouseX);
    	InputComponent->BindAxis("MouseControlY", this, &ADellPawn::MouseY);
    }
    
    void ADellPawn::PossessedBy(AController* NewController)
    {
    	// Assign the new controller
    	Controller = NewController;
    }

void ADellPawn::PossessedBy(AController* NewController)
{
	// Assign the new controller
	Controller = NewController;
}

void ADellPawn::MoveForward(float AxisValue)
{
	
	if (AxisValue != 0.0f)
		CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100;
		//GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Red, " , " + FString::SanitizeFloat(1555555551.f));
		//AddMovementInput(GetActorForwardVector(), Value, true);
}

this is at the top of my pawnmovementcomp.cpp

class ADellPawn;

You can see I tried AddMovementInput(GetActorForwardVector(), Value, true) but that didnt work.

I have managed to get MoveForward() to print a string so I know it works, its just the movement part (cant even set velocity).

Could it be due to something wrong with my player controller? In my game mode blueprint I have a unrelated controller selected but I cant select nothing so I really dont know what to do. Please help! I have been trying for ages to get this to work.

Hi Lawrie,

I cannot seem to find any error in the code you posted. However, could you please post the constructors of your Pawn and PawnMovementComponent as well? If your pawn is inheriting from ACharacter class then you don’t really need to build a new movement component. You can simply access it and change its values anywhere in your character class.

One more thing, are you getting any warning in the editor when you play the game? Your pawn mobility might have been accidentally set to static or stationary which will prevent it from moving (however you should get warning messages if you try to move it). With regards to your GameMode, as long as the MoveForward is getting called and the AxisValue is larger than 0 then you shouldn’t have any problem with it. However, just to be sure, if you don’t any Controller then set the GameMode controller to use the base PlayerController class.

Let me know how it goes :slight_smile:

Thanks for responding.

My pawn doesnt inherit from character (atleast I dont think so). The reason why I m not using just a character is because I would rather not have some of the things that are in the character movement because they conflict with some functionality I want to implement (specifically strafe jumping/ air strafing). I have managed to implement strafejumping in c++ and blueprint but only using Character classes. However it doesnt quite feel right, and things like friction and speed mess up. I was under the impression that I can have a normal pawn, and then attach a pawn movement component to it and be able to code simple movement controls (like addmovementinput() etc).

I checked and no warnings in the editor, so I dont think its being set to static.

Here are my classes.

my pawns .h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Components/BoxComponent.h"
#include "DellPawn.generated.h"

class UDellPawnMoveComp;
class UCameraComponent;

UCLASS()
class DELLMOD_API ADellPawn : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	ADellPawn();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	

	/** Called when the character changes controller or gets a new one */
	virtual void PossessedBy(AController* NewController);

	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;

	AController* Controller;

public:

	/** Character's movement component */
	UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
		UDellPawnMoveComp* MovementComponent;

	//Pawns Collision
	UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
		UBoxComponent* PawnCollision;

	//Pawns Forward Reference
	USceneComponent* PawnForward;

	//Pawns Camera
	UCameraComponent* PawnCamera;

	

	/* X is forward [W] and back [S] (1.0 to -1.0) and Y is right [D] and left [A] (1.0 to - 1.0) */
	UPROPERTY(Category = Input, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
		FVector2D MovementInput;

	/* Stores relational (to last frame) mouse position */
	FVector2D MouseVelocity;

	/** Handles moving forward/backward */
	void MoveForward(float Value);

	/** Handles strafing movement, left and right */
	void MoveRight(float Value);

	/** Mouse movement input callbacks */
	void MouseX(float Value);
	void MouseY(float Value);

	void StartJump();
	void StopJump();

	FVector CurrentVelocity;

};

my pawn’s pawnmovementcomponent .h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PawnMovementComponent.h"
#include "DellPawnMoveComp.generated.h"


class ADellPawn;

/**
 * 
 */
UCLASS()
class DELLMOD_API UDellPawnMoveComp : public UPawnMovementComponent
{
	GENERATED_BODY()

public: 
	/** Character this belongs to */
	ADellPawn* Player;

	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;

	FVector2D WishMove;

	void QueueJump();
	
};

my pawn’s pawnmovementcomponent .cpp

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

#include "DellPawnMoveComp.h"
#include "DellPawn.h"
#include "Engine.h"

class ADellPawn;

void UDellPawnMoveComp::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	// Grab the input from the player
	//WishMove = Player->ConsumeMovementInput();
	FVector Invec = FVector(1000, 3000, 0);
	AddInputVector(Invec, true);
	//Player->AddMovementInput(Invec, 1, true);
	
	//PawnOwner->AddMovementInput(PawnOwner->GetActorForwardVector(), 1, true);
	//Velocity.X = 4000.f;
	//UpdateComponentVelocity();

	GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::White,  " , " + FString::SanitizeFloat(52221.f));
}


void UDellPawnMoveComp::QueueJump()
{
	//Velocity.Z = 500.f;
}

my pawn’s .cpp

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

#include "DellPawn.h"
#include "Engine.h"
#include "DellPawnMoveComp.h"
#include "Components/BoxComponent.h"



// Sets default values
ADellPawn::ADellPawn()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;


	//Create Pawns Collision
	PawnCollision = CreateDefaultSubobject<UBoxComponent>(TEXT("Pawns Collision"));
	PawnCollision->InitBoxExtent(FVector(30.f, 30.f, 62.f));
	
	//Set Collision As Root
	RootComponent = PawnCollision;
	
	//Create Reference To Players Forward Vector
	PawnForward = CreateDefaultSubobject<USceneComponent>(TEXT("Pawns Forward Reference"));
	if (PawnForward) {
		PawnForward->AttachTo(PawnCollision);	//Attach Forward Reference To Collision
	}

	PawnCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("Pawn Camera"));

	if (PawnCamera) {
		PawnCamera->SetRelativeLocation(FVector(0.f, 0.f, 62.f - 4.f));
	}

	MovementComponent = CreateDefaultSubobject<UDellPawnMoveComp>(TEXT("Pawn Movement Component"));
	MovementComponent->UpdatedComponent = PawnCollision;



	// Take control of the default player
	AutoPossessPlayer = EAutoReceiveInput::Player0;


}

// Called when the game starts or when spawned
void ADellPawn::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ADellPawn::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	//FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
//	SetActorLocation(NewLocation);

}

// Called to bind functionality to input
void ADellPawn::SetupPlayerInputComponent(UInputComponent* InputComponent)
{
	Super::SetupPlayerInputComponent(InputComponent);

	check(InputComponent);

	// Set up movement
	InputComponent->BindAxis("ForwardMovement", this, &ADellPawn::MoveForward);
	InputComponent->BindAxis("RightMovement", this, &ADellPawn::MoveRight);

	InputComponent->BindAction("Jump", IE_Pressed, this, &ADellPawn::StartJump);
	InputComponent->BindAction("Jump", IE_Released, this, &ADellPawn::StopJump);

	// Set up mouse inputs
	InputComponent->BindAxis("MouseControlX", this, &ADellPawn::MouseX);
	InputComponent->BindAxis("MouseControlY", this, &ADellPawn::MouseY);
}

void ADellPawn::PossessedBy(AController* NewController)
{
	// Assign the new controller
	Controller = NewController;
}

void ADellPawn::MoveForward(float AxisValue)
{
	
	if (AxisValue != 0.0f)
		CurrentVelocity.X = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100;
		//GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Red, " , " + FString::SanitizeFloat(1555555551.f));
		//AddMovementInput(GetActorForwardVector(), Value, true);
}

void ADellPawn::MoveRight(float AxisValue)
{
	if (AxisValue != 0.0f)
		//CurrentVelocity.Y = FMath::Clamp(AxisValue, -1.0f, 1.0f) * 100;
		AddMovementInput(GetActorRightVector(), AxisValue, true);
}

void ADellPawn::MouseX(float Value)
{
	FVector v(0.f, 0, Value);
	PawnCamera->AddWorldRotation(FQuat::MakeFromEuler(v));
}

void ADellPawn::MouseY(float Value)
{
	FVector v(0, -Value, 0);
	PawnCamera->AddLocalRotation(FQuat::MakeFromEuler(v));
}

void ADellPawn::StartJump()
{
	//MovementComponent->AddInputVector((FVector(0, 0, 700.f)), true);
	MovementComponent->Velocity.Z = 600.f;
	
	//GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::White, " , " + FString::SanitizeFloat(11.f));
}


void ADellPawn::StopJump()
{
	//MovementComponent->Velocity.Z = 600.f;
}

Sorry its really messy, and most of it is commented anyway, if you want a clearer version just with the constructors i can do that. Thanks

Hey, I replied as an answer because the comment wouldnt let me post that long of a comment. Thanks

I think you’re just making your life much harder by creating everything from scratch! Try to use this game engine to your advantage and get the most out of it :slight_smile: You see, the already implemented and optimized character class will take care of literally everything for you (movement, playing differenct animations, etc.). You will have to implement all of these functionalities from scratch if you go with base classes! Instead, you can very easily disable or extend some of the character’s functionalities and implement your very own behaviors. You can even do these in blueprints!

Now back to why your pawn doesn’t move. It’s because base Pawn classes don’t have any movement algorithm implemented. In fact, if you read the comment for AddMovementInput() function in the engine source code, you will see that it says “Base pawn classes won’t apply movement automatically and it is up to the user to do so in the tick component”. How would you do so? You will need to update bone positions, actor location, rotation, etc. Trust me that’s a lot of work to get a character moving, so don’t make your life any harder and instead take full advantage of what this awesome engine already equips you with :slight_smile: So where to start? If you want a character that stands on two legs, start with Character class as your base class (Or even easier go with ThirdPersonCharacter project for C++). If you want a pawn that floats/flies, then go with FloatingPawnMovement component or Flying Template.

For this particular case, the easiest way is the best way :wink:

Hope this helps!

P.S. If you still want to implement your own pawn movement then I suggest you start with this official tutorial here.

ah ok. You are right, there’s no way I would be able to do that, but I was thinking the pawnmovementcomponent had some of the basics similar to the character but I guess not.

So I could go and create a character, and then a custom charactermovementcomponent and set that as the characters movement comp (I have done this and I can get it working alright). But could I perhaps make a pawn, and then make and attach a custom charactermovementcomponent to the pawn?

Basically I want to make a new pawn use these components (and not the ones that come with a default character);
simple box collision, camera and an empty character movement component which is empty (but has access to the movement stuff, so I can just write my own movement (not the complicated stuff, just the simple stuff like addmovementinput() etc and it would work?)

(iam sure I could go through and delete stuff i dont want (like the default skeletal mesh component etc) but I would rather just choose what i want rather than go and have to delete all things I dont)

Thanks for you help :).

Ideally actually I want a character class that is empty, but still has all the ability to code the same things that would come in a default character class.

You said you can disable and extend parts of the character class to get a more custom class. I think I understand a bit about extending but about disabling, how would you go about totally disabling certain functions/features of a parent (character) in the child (my character class) ?

Yes, you can absolutely make your own character movement behavior from scratch, but the question is, does that worth the time and effort?!

Want an empty class? Create a new c++ class based on Character and it will be an empty c++ class. Now, you’re inheriting from both pawn and character.

Want to disable some functionalities? Then don’t use them! it’s as simple as that! Some unused code sitting somewhere in your project will not hurt your game at all!

Do you want to use the walking/running functionalities but thinking of implementing your own jump method? then use the inherited walking/running methods and when it comes to jumping, use your own jump method.

There you go, a modified character class :slight_smile:

Hi Lawrie,

Please consider marking this question as “resolved” if your problem has been addressed to help us better filter unanswered questions. Thanks :slight_smile: