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!

Another common reason why a pawn/actor/character’s BeginPlay()/Tick() methods would not get called is when you don’t spawn them from the gamemode. In other words, if your blueprint is not spawned (placed in the scene), then the corresponding methods (e.g. beginplay(), tick(), …) would not get called. Thus, you should do two things: verify that your custom gamemode is selected, and make sure you spawn the target pawn/actor/charactor from your custom gamemode :

1- To select your custom gamemode (e.g. BP_gamemode), within Unreal editor, go to Edit->Projet Settings->Maps&Modes:

2- Spawn the class whose beginplay method needs to be called using the following statement in your custom gamemode (e.g. BP_gmaemode.cpp) as follow:
BP_gamemode.cpp::BeginPlay()

// ....
FVector Location;
FRotator Rotation;
Cast<AActor>(GetWorld()->SpawnActor<AMyPawnClassName>(AMyPawnClassName::StaticClass(),Location,Rotation)));
// ....