I have managed to compile without errors.
This is the lecture where we made a PlayerControllerBase class, then wrote in references to this new class in the TankGameModeBase .cpp and .h files.
TankGameModeBase.h
class APlayerControllerBase; // forward declaration
private:
APlayerControllerBase* PlayerControllerRef;
.
TankGameModeBase.cpp
void ATankGameModeBase::HandleGameStart()
{
PlayerControllerRef = Cast<APlayerControllerBase>(UGameplayStatics::GetPlayerController(this, 0));
.
. //rest of code not included
}
^^ The above Cast fails.
As part of troubleshooting I created the next line…
if (!PlayerControllerRef) UE_LOG(LogTemp, Error, TEXT("!PlayerControllerRef"));
And the LOG confirms that UE4 cannot make a reference to APlayerController.
Removing the Cast and simply having the APlayerControllerBase* PlayerControllerRef;
declaration from the Header file gives the same result - no reference to the PlayerController.
The other casts work.
ie- PlayerTank = Cast<APawnTank>(UGameplayStatics::GetPlayerPawn(this, 0));
And I have checked the #includes and forward declarations.
As I said, everything compiles.
I’m not sure where else to look.
DanM
July 28, 2021, 11:00am
2
That would imply that the player controller isn’t using your APlayerControllerBase
class. What do you have in the game mode?
The c++ Game Mode files ?
Or do you mean some other GameMode relationship ?
TankGameModeBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "TankGameModeBase.generated.h"
class APawnTurret;
class APawnTank;
class APlayerControllerBase;
class ATankGameModeBase;
UCLASS()
class TOONTANKS_API ATankGameModeBase : public AGameModeBase
{
GENERATED_BODY()
private:
APawnTank* PlayerTank;
int32 TargetTurrets = 0;
int32 GetTargetTurretCount();
APlayerControllerBase* PlayerControllerRef;
ATankGameModeBase* GameModeRef;
void HandleGameStart();
void HandleGameOver(bool PlayerWon);
public:
void ActorDied(AActor* DeadActor);
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Game Loop")
int32 OnYourMarks = 5;
virtual void BeginPlay() override;
UFUNCTION(BlueprintImplementableEvent)
void GameStart();
UFUNCTION(BlueprintImplementableEvent)
void GameOver(bool PlayerWon);
};
.
.
.
TankGameModeBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "ToonTanks/GameModes/TankGameModeBase.h"
#include "ToonTanks/Pawns/PawnTank.h"
#include "ToonTanks/Pawns/PawnTurret.h"
#include "Kismet/GameplayStatics.h"
#include "TimerManager.h"
#include "ToonTanks/PlayerControllers/PlayerControllerBase.h"
#include "GameFramework/Actor.h"
void ATankGameModeBase::BeginPlay()
{
// get references and the game win/lose conditions.
Super::BeginPlay();
HandleGameStart();
// call HandleGameStart() to initialise the start countdown, turret activation, pawn check, etc...
}
void ATankGameModeBase::ActorDied(AActor* DeadActor)
{
// All died Actors get passed in here.
// check what type of actor died.
// If Turret, then tally. If player, then go to lose condition.
if (DeadActor == PlayerTank)
{
PlayerTank->ManageDestruction();
if (PlayerControllerRef)
{
PlayerControllerRef->SetPlayerEnabledState(false);
}
HandleGameOver(false);
}
else if (APawnTurret* DestroyedTurret = Cast<APawnTurret>(DeadActor))
{
DestroyedTurret->ManageDestruction();
--TargetTurrets;
if (TargetTurrets <=0)
{
HandleGameOver(true);
}
}
UE_LOG(LogTemp, Error, TEXT("DEAD SKUNK !! void ATankGameModeBase::ActorDied(AActor* DeadActor)"));
}
int32 ATankGameModeBase::GetTargetTurretCount()
{
TArray<AActor*> TurretActors; //OUT parameter
UGameplayStatics::GetAllActorsOfClass(GetWorld(), APawnTurret::StaticClass(), TurretActors);
return TurretActors.Num();
}
void ATankGameModeBase::HandleGameStart()
{
// initialise the start countdown, turret activation, pawn check, etc...
TargetTurrets = GetTargetTurretCount();
PlayerTank = Cast<APawnTank>(UGameplayStatics::GetPlayerPawn(this, 0));
PlayerControllerRef = Cast<APlayerControllerBase>(UGameplayStatics::GetPlayerController(this, 0));
if (!PlayerControllerRef) UE_LOG(LogTemp, Error, TEXT("!PlayerControllerRef"));
GameStart();
if (PlayerControllerRef)
{
PlayerControllerRef->SetPlayerEnabledState(false);
FTimerHandle PlayerEnableHandle;
FTimerDelegate PlayerEnableDelegate;
PlayerEnableDelegate = FTimerDelegate::CreateUObject(PlayerControllerRef,
&APlayerControllerBase::SetPlayerEnabledState,
true);
GetWorld()->GetTimerManager().SetTimer(PlayerEnableHandle, PlayerEnableDelegate, OnYourMarks, false);
}
}
void ATankGameModeBase::HandleGameOver(bool PlayerWon)
{
// See if the player has destroyed the turrets, show in result.
// else if turret destroyed player, show lose result.
// call blueprint version.... GameOver(bool)
GameOver(PlayerWon);
}
DanM
July 28, 2021, 11:42am
4
No, the settings in maps & modes
1 Like
Ahh, yes.
Thankyou.
It had to be something quick and clean like that.
Problem solved
system
Closed
July 29, 2021, 11:54am
6
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.