Gameplay Pillars
- >Immersive AI presence that enhances tension
- >Reactive enemy behavior driven by player actions
- >Enemy encounters that remain challenging without feeling unfair
Gameplay Programmer
Developed and maintained AI behavior systems, player-AI interactions, AI-environment interactions, and UI features. The goal was to create a responsive and immersive AI that felt constantly present in the game world, increasing player tension and enhancing the overall horror experience.
Duration
4 months
Team
3 developers
Engine
Unreal Engine 5
Platforms
PC
Practical samples from gameplay systems and runtime tools used in production.
BTTask_MeleeAttack.cpp | cpp
Behavior tree task that checks if the player is in range and executes the monster's melee attack.
#include "BTTask_MeleeAttack.h"
#include "Monster_AIController.h"
#include "DarkChamber/DarkChamberCharacter.h"
UBTTask_MeleeAttack::UBTTask_MeleeAttack()
{
NodeName = TEXT("Melee attack");
}
EBTNodeResult::Type UBTTask_MeleeAttack::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
//if not in range, don't attack the player
auto const OutOfRange = !OwnerComp.GetBlackboardComponent()->GetValueAsBool(GetSelectedBlackboardKey());
if(OutOfRange)
{
//Finish task
FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded);
return EBTNodeResult::Succeeded;
}
auto const * const Controller = OwnerComp.GetAIOwner();
auto* const Monster = Cast<AMonster>(Controller->GetPawn());
//If the Monster supports the Combat Interface, call and execute the Attack function
if(auto* const ICombat = Cast<ICombatInterface>(Monster))
{
if(auto* const Player = Cast<ADarkChamberCharacter>(Controller->GetPawn()))
{
Player->PlayerHealth->ReduceHealth(Monster->AttackDamage);
}
ICombat->Execute_MeleeAttack(Monster);
}
FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded);
return EBTNodeResult::Type();
}Monster.cpp | cpp
Implementation for monster that involve traps, using interfaces.
void AMonster::HoleAttack_Implementation()
{
CharacterMovement->Deactivate();
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &AMonster::SetMovement, 7.0f, false, 5);
GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, "HoleAttack");
}
void AMonster::EletricAttack_Implementation()
{
CharacterMovement->Deactivate();
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &AMonster::SetMovement, 5.0f, false, 5);
GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, "EletricAttack");
}