Symptoms: (Are the first 2 important at all?)
-When I started the project and pressed play, not the third person character came up, just a floating bodyless camera that bumps into walls.
-I changed the gamemode to GameMode_BP, changed the pawn to “ThirdPersonCharacter”, then the body came back without decreasing, same with “BatteryCollectorCharacter”.
-Then changed back the gamemode to the “BatteryCollectorGameMode”, now it works the same.
-The game mode should decrease the power. The Tick override should work. The casting should work. Then why it isn’t happening?
Here is the Tick function:
void ABatteryCollectorGameMode::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//Check that we are using the battery collector character
ABatteryCollectorCharacter* MyCharacter = Cast<ABatteryCollectorCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));
if (MyCharacter)
{
//If the character's power is greater than needed to win, set the game's state to Won
if (MyCharacter->GetCurrentPower() > PowerToWin)
{
SetCurrentState(EBatteryPlayState::EWon);
}
//If the character's power is positive
if (MyCharacter->GetCurrentPower() > 0)
{
//Decrease the character's power using the decay rate
MyCharacter->UpdatePower(-DeltaTime*DecayRate*(MyCharacter->GetInitialPower()));
}
else
{
SetCurrentState(EBatteryPlayState::EGameOver);
}
}
}
The character still can collect the batteries, and the play state can change to “EWon”, so this must be working, but something happens between the 2 “if”?
void ABatteryCollectorCharacter::UpdatePower(float PowerChange)
{
//Change power
CurrentPower += PowerChange;
//Change speed based on power
GetCharacterMovement()->MaxWalkSpeed = BaseSpeed + SpeedFactor * CurrentPower;
//Call visual effect
PowerChangeEffect();
UE_LOG(LogClass, Warning, TEXT("UpdatePower - done"));
}
And I get that “UpdatePower - done” after every Tick. I watch the powerlevel from the progressbar, the character speed, and the character’s color, and they all change when I collect a battery, but still no decrease.
DecayRate shouldn’t be a problem either, since it’s value is set in the GameMode’s contructor to 0.075f. (and it IS a float variable)
Maybe it always return the same value, so “no power decrease” even if it is called.
That will be for the UI… if your movement is decreasing at the end before die, and you are not seeing the update on the UI, maybe you havent setup correctly the UI event and update, so you dont see it.
Tried with this UE_LOG to localize why it doesn’t change. The reason: The DecayRate IS 0. But there is no reason to be that.
I have this contructor:
ABatteryCollectorGameMode::ABatteryCollectorGameMode()
{
// set default pawn class to our Blueprinted character
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter"));
if (PlayerPawnBPClass.Class != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Class;
}
UE_LOG(LogClass, Warning, TEXT("GameMode Contructor 1"));
//Base decay rate
DecayRate = 0.075f;
UE_LOG(LogClass, Warning, TEXT("GameMode Contructor 2"));
}
And I get:
LogClass:Warning: GameMode Contructor 1: 0.000000
LogClass:Warning: GameMode Contructor 2: 0.075000, as it should be.
But it still becomes 0 in the Tick function. (“LogClass:Warning: UpdatePower DecayRate? 0.000000”
And idea why?
The only way to know why it gets reset to 0 would be to searhc in all the project for the variable, and set breakpoints to see where it gets reset to cero.
To be able to catch breakpoints, you should attach vs to the UE4 process or, hit run from VS, this will launch another instance of the editor if you launched it from the epic launcher, ad it will break on the brakpoints you have setup.
probably… in any case, for the moment, you can setup directly with a hardcoded constant or inside the update ask if the value is zero set it to the correct value xD… (and see if it doesnt get reset to zero each tick… which would be strange).
It could be a second game mode, dont know, but I guess if you print “this” and you get different hex values for the address, it could be a different game mode…
in any case here is my code for that tut game mode
#include "BatteryCollector.h"
#include "BatteryCollectorGameMode.h"
#include "BatteryCollectorCharacter.h"
#include "Kismet/GameplayStatics.h"
#include "Blueprint/UserWidget.h"
#include "SpawnVolume.h"
void ABatteryCollectorGameMode::PrepareSpawnVolumes()
{
// find all spawn volume actors
TArray<AActor*> FoundActors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ASpawnVolume::StaticClass(), FoundActors);
for (auto Actor : FoundActors)
{
ASpawnVolume* SpawnVolumeActor = Cast<ASpawnVolume>(Actor);
if (SpawnVolumeActor)
{
SpawnVolumeActors.AddUnique(SpawnVolumeActor);
}
}
}
void ABatteryCollectorGameMode::BeginPlay()
{
Super::BeginPlay();
PrepareSpawnVolumes();
SetCurrentState(EBatteryPlayState::EPlaying);
// set the score to beat
ABatteryCollectorCharacter* MyCharacter = Cast<ABatteryCollectorCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));
if (MyCharacter)
{
PowerToWin = (MyCharacter->GetInitialPower())*1.54f;
}
if (HUDWidgetClass != nullptr)
{
CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), HUDWidgetClass);
if (CurrentWidget != nullptr)
{
CurrentWidget->AddToViewport();
}
}
}
ABatteryCollectorGameMode::ABatteryCollectorGameMode()
{
// set default pawn class to our Blueprinted character
static ConstructorHelpers::FClassFinder<APawn> PlayerPawnBPClass(TEXT("/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter"));
if (PlayerPawnBPClass.Class != NULL)
{
DefaultPawnClass = PlayerPawnBPClass.Class;
}
// base decay rate
DecayRate = 0.01f;
}
void ABatteryCollectorGameMode::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
ABatteryCollectorCharacter* MyCharacter = Cast<ABatteryCollectorCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));
if (MyCharacter)
{
if (MyCharacter->GetCurrentPower() > PowerToWin) {
SetCurrentState(EBatteryPlayState::EWon);
}
if (MyCharacter->GetCurrentPower() > 0) {
MyCharacter->UpdatePower(-DeltaTime*DecayRate*(MyCharacter->GetInitialPower()));
}
else {
SetCurrentState(EBatteryPlayState::EGameOver);
}
}
}
float ABatteryCollectorGameMode::GetPowerToWin()
{
return PowerToWin;
}
EBatteryPlayState ABatteryCollectorGameMode::GetCurrentState() const
{
return CurrentState;
}
void ABatteryCollectorGameMode::SetCurrentState(EBatteryPlayState NewState)
{
CurrentState = NewState;
HandleNewState(CurrentState);
}
void ABatteryCollectorGameMode::HandleNewState(EBatteryPlayState NewState)
{
UE_LOG(LogClass, Warning, TEXT("handling new state"));
switch (NewState) {
case EBatteryPlayState::EPlaying:
UE_LOG(LogClass, Warning, TEXT("handling playing state!"));
// spawn volumes active
for (ASpawnVolume* Volume : SpawnVolumeActors)
{
Volume->SetSpawningActive(true);
}
break;
case EBatteryPlayState::EWon:
UE_LOG(LogClass, Warning, TEXT("handling won state!"));
// spawn volumes inacive
for (ASpawnVolume* Volume : SpawnVolumeActors)
{
Volume->SetSpawningActive(false);
}
break;
case EBatteryPlayState::EGameOver:
{
UE_LOG(LogClass, Warning, TEXT("handling game over state!"));
// spawn volumes inactive
for (ASpawnVolume* Volume : SpawnVolumeActors)
{
Volume->SetSpawningActive(false);
}
// block player input
APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0);
if (PlayerController)
{
PlayerController->SetCinematicMode(true, false, true);
}
// ragdoll the character
ACharacter* MyCharacter = Cast<ACharacter>(UGameplayStatics::GetPlayerCharacter(this, 0));
if (MyCharacter)
{
MyCharacter->GetMesh()->SetSimulatePhysics(true);
MyCharacter->GetMovementComponent()->MovementState.bCanJump = false;
}
}
break;
default:
case EBatteryPlayState::EUnknow:
UE_LOG(LogClass, Warning, TEXT(" game state is unknow!"));
break;
}
}
Oh, god. I found the problem, but still don’t know how it could have happened. There was a Blueprint made from the BatteryCollectorGameMode, called GameMode_BP, and this was used. And in Its blueprint was the DecayRate set to 0 manually. Goddamit… So I put it back to Default Value, now it works as it should. Thank you for your patience, and I can’t belive how dumb problem it was…:mad:
Well, Im still not found on the make logic in C and assign values i BP xD… so… it passed my head a couple of times, but I didnt take the hint… xD GL && HF.