Enemies Recognizing Player Death

I just wanted to do something simple here, but I always laugh at AI that continue to shoot or fight after the player dies, so I decided to modify the code here so that the AI just looses sight of the player on death.

I will give it to you, that I’ve seen this solution used before in games where AI just seems to forget everything that happened when the player dies and they just start doing their normal routine. Survives epic battle with lighting and dragons! “Must have been the wind.”

Anyway, this goes into the UBTService_PlayerLocationIfSeen class, or the “Update Player Location is Seen” service as a modification to the TickNode.

void UBTService_PlayerLocationIfSeen::TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) 
{
    Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);

    APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
    AAIController* AIOwner = OwnerComp.GetAIOwner();

    if (!IsValid(AIOwner))
    {
        return;
    }

    if (!IsValid(PlayerPawn))
    {
        AIOwner->GetBlackboardComponent()->ClearValue(GetSelectedBlackboardKey());
        return;
    }

    if (AIOwner->LineOfSightTo(PlayerPawn))
    {
        AIOwner->GetBlackboardComponent()->SetValueAsVector(GetSelectedBlackboardKey(), PlayerPawn->GetActorLocation());
    }
    else
    {
        AIOwner->GetBlackboardComponent()->ClearValue(GetSelectedBlackboardKey());
    }
}

Basically, what I did was move some of the returns around so that I could have the PlayerPawn nullptr check return double to clear the selected blackboard key, which is player location in this case.

This means that once the AI kills the player, they’ll continue their normal routine, which is advancing to the last known player location before returning after an amount of time has passed. I also had to move AI Owner Around to be before the PlayerPawn check so that I could actually clear the key without throwing a nullptr error.

I think for this instance, this is a pretty good way to go, although I see this breaking down if the player is facing too many enemies as when the player dies, they’ll all advance on the player position, curious at what they have just done.

You could power this up a lot by putting this functionality in its own service and create another key to check that we could call bTargetAlive.

Once you flip that the bTargetAlive key to false, you can have it execute custom functionality like walking up to the target and kneeling as if looting, or verifying if the character is still “alive.” With a group you could create another service for this same branch that would fire an event to the game mode, and have the game mode grant that functionality to a limited number of AI units so that an entire group doesn’t check walk up to the player.

I feel like that in itself would be more of a Task, that could only be performed if two flags are true. So you would check if bTargetAlive is true, and then check if bCheckPlayerBody are true before that. I think that would make a much more immersive experience.

1 Like

Thank you for doing this. I was struggling with the same thing.

1 Like

Privacy & Terms