Editor crashes when player dies

Hello everyone, I have a question. I make small tanks game and when player dies editor crashes and in error log is written that error is on line " PlayerLocation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation();". So I want to ask why it even works if earlier is said that if player is not null pointer it should not be done.

void AEnemy::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);

if(PlayerTank != nullptr)
{
    if(EnemyAI)
    {
        FCollisionQueryParams CollisionParams;
        CollisionParams.AddIgnoredActor(this);
        PlayerLocation = GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation();
        EnemyLocation = GetActorLocation();

        GetWorld()->LineTraceSingleByChannel(HitResult, EnemyLocation, PlayerLocation, ECC_Visibility, CollisionParams, FCollisionResponseParams());
        
        DrawDebugLine(GetWorld(), EnemyLocation, PlayerLocation, FColor::Red, false, 0.5f);
    }
}

}

Is PlayerTank from the if condition your player pawn ? if so you could get the location from that instead of going through the controller

as for the crash, it’s one of the Gets() that is failing and then the get after it is trying to run but it’s running from a nullptr so it crashes because nullptr doesn’t have method GetX()
You could debug this by doing you gets sequentially

World = GetWorld();
PlayerController = World->GetFirstPlayerController();
Pawn = PlayerController->GetPawn();
PlayerLocation = Pawn->GetActorLocation();

(Not real C++)
This way you can now exactly which part is causing the editor to crash

You are running this on tick so this is probably where you are encountering the crash

GetWorld()->GetFirstPlayerController() -/->GetPawn() -/->GetActorLocation();

I’m guessing that if the player dies, it’s controlled pawn is destroyed. If so GetPawn() will return a nullptr and you can’t call GetActorLocation() on an invalid actor.

Cache GetWorld()->GetFirstPlayerController()->GetPawn() to a APawn pointer and then do a null check on it. If it passes then you can call GetActorLocation on it.

If the cached APawn is nullptr then skip all of the code below (so no line trace and draw debug)

You could also do a check for the GetFirstPlayerController controller as it too can return nullptr

void AEnemy::Tick(float DeltaTime)
{
        Super::Tick(DeltaTime);

        if(PlayerTank != nullptr){
                if(EnemyAI){
                        FCollisionQueryParams CollisionParams;
                        CollisionParams.AddIgnoredActor(this);

                        APlayerController * pc = GetWorld()->GetFirstPlayerController();
                        if(pc!=nullptr){
                                APawn* pawn = pc->GetPawn();
                                if(pawn!=nullptr){
                                        PlayerLocation = pawn->GetActorLocation();
                                        EnemyLocation = GetActorLocation();
                                        GetWorld()->LineTraceSingleByChannel(HitResult, EnemyLocation, PlayerLocation, ECC_Visibility, CollisionParams, FCollisionResponseParams());        
                                        DrawDebugLine(GetWorld(), EnemyLocation, PlayerLocation, FColor::Red, false, 0.5f);
                                }
                        }
                }
        }
}

Just double check the closing bracket amount as it’s just guess code with no IDE to test it.

Though personally I would use
UGameplayStatics::GetPlayerController to get the player controller

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.