Pawn Begin Play event not called (C++)

Hi everybody

I have created my own GameMode, GameState and Pawn classes in my project. I wanted to setup the input for my pawn but the pawn didn’t react to it. Therefore I added some debug messages and found that neither the Tick nor the BeginPlay methods are being called. Why is this the case?

GameMode:

(Header)

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameMode.h"
#include "Factorybelts2GameModeBase.generated.h"

/**
 * 
 */
UCLASS()
class FACTORYBELTS2_API AFactorybelts2GameModeBase : public AGameModeBase
{
	GENERATED_BODY()
	
public:
	AFactorybelts2GameModeBase();
	
	
};


(Body)

#include "Factorybelts2GameModeBase.h"
#include "FactoryBelts2GameState.h"
#include "FactoryBelts2PlayerController.h"
#include "FactoryBelts2Pawn.h"

AFactorybelts2GameModeBase::AFactorybelts2GameModeBase() {
	GameStateClass = AFactoryBelts2GameState::StaticClass();
	PlayerControllerClass = AFactoryBelts2PlayerController::StaticClass();
	DefaultPawnClass = AFactoryBelts2Pawn::StaticClass();
}

GameState:

(Header)

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameState.h"
#include "FactoryBelts2GameState.generated.h"

/**
 * 
 */
UCLASS()
class FACTORYBELTS2_API AFactoryBelts2GameState : public AGameStateBase
{
	GENERATED_BODY()
	
public:
	virtual void HandleBeginPlay() override;
	void ToggleSimulation();
	bool GetSimulationState();

private:
	class AGrid* ActiveGrid;
	bool bSimulationRunning;
	
	
};

(Body)

#include "FactoryBelts2GameState.h"
#include "EngineUtils.h"
#include "Grid.h"

void AFactoryBelts2GameState::HandleBeginPlay() {
	TActorIterator<AGrid> ActorIter(GetWorld());
	ActiveGrid = *ActorIter;
	FString GridName = ActiveGrid->GetName();
	bSimulationRunning = false;
	ActiveGrid->SetSimulationState(false);
}

void AFactoryBelts2GameState::ToggleSimulation() {
	bSimulationRunning = !bSimulationRunning;
	ActiveGrid->SetSimulationState(bSimulationRunning);
}

bool AFactoryBelts2GameState::GetSimulationState() {
	return bSimulationRunning;
}

Pawn:

(Header)

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "FactoryBelts2Pawn.generated.h"

UCLASS()
class FACTORYBELTS2_API AFactoryBelts2Pawn : public APawn
{
	GENERATED_BODY()

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

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

	class UCameraComponent* MainCamera;
	class USceneComponent* DummyRoot;

	void Rotate(float AxisValue);

	float RotationFactor;

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

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

	
	
};

(Body)

#include "FactoryBelts2Pawn.h"
#include "Runtime/Engine/Classes/Camera/CameraComponent.h"

// Sets default values
AFactoryBelts2Pawn::AFactoryBelts2Pawn()
{
 	// 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;
	//AutoPossessPlayer = EAutoReceiveInput::Player0;
	RotationFactor = 0;
	DummyRoot = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
	MainCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MainCamera"));
	RootComponent = DummyRoot;
	MainCamera->SetupAttachment(RootComponent);
	MainCamera->SetRelativeLocation(FVector(10,0,5));
	UE_LOG(LogTemp, Warning, TEXT("Pawn Construction"));
}

// Called when the game starts or when spawned
void AFactoryBelts2Pawn::BeginPlay()
{
	UE_LOG(LogTemp, Warning, TEXT("Pawn Begin Play"));
	Super::BeginPlay();
}

// Called every frame
void AFactoryBelts2Pawn::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	FRotator Rotation = FRotator(RotationFactor * DeltaTime, 0, 0);
	UE_LOG(LogTemp, Warning, TEXT("Rotation %f"), RotationFactor);
	AddActorWorldRotation(Rotation);
}

// Called to bind functionality to input
void AFactoryBelts2Pawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	UE_LOG(LogTemp, Warning, TEXT("Pawn Setup"));
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	InputComponent->BindAxis("RotateView", this, &AFactoryBelts2Pawn::Rotate);

}

void AFactoryBelts2Pawn::Rotate(float AxisValue) {
	RotationFactor = AxisValue * 100;
}

I assume you assigned your custom gamemode to the level?

I don’t see where you have placed the pawn in the world. I assume you created a blueprint that inherits your custom pawn class and then placed it in the world?

I chose to use the SetupInputComponent() off the Controller.

I assigned my gamemode in the projectsettings as the default gamemode to use. I have not created a blueprint that inherits from my pawn and I have not placed my pawn in the world. As far as I understand the functionality of the gamemode, it handles the spawning of a pawn and I do not need to place one in the level explicitly. Am I wrong in this assumption?

Sigh…

I FINALLY found the problem: In my custom GameState class, I have overridden the HandleBeginPlay method, but didn’t call the super method. So after adding

Super::HandleBeginPlay();

to my custom GameState, everything worked as expected. I wish there was a warning for missing supercalls…

Congrats! That has bitten me a time or two as well!