
void AMonsterAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
if (IsValid(BehaviorTree))
{
UseBlackboard(BehaviorTree->BlackboardAsset, (UBlackboardComponent*&)BlackboardComponent);
RunBehaviorTree(BehaviorTree);
LOG(TEXT("AIController Possess"));
// Initialize BlackboardKey (CurrnetState, TargetActor)
BlackboardComponent->SetValueAsEnum("MonsterState", static_cast<uint8>(EMonsterState::Patrol));
BlackboardComponent->ClearValue("TargetActor");
}
FTimerHandle TimerHandle;
GetWorldTimerManager().SetTimer(TimerHandle, this, &AMonsterAIController::InitializePatrolPoint, 0.5f, false);
}
void AMonsterAIController::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (!bIsLosingTarget) return;
float Elapsed = GetWorld()->GetTimeSeconds() - LostTargetTime;
if (Elapsed > SightConfig->GetMaxAge())
{
BlackboardComponent->ClearValue("TargetActor");
BlackboardComponent->SetValueAsEnum("MonsterState", static_cast<uint8>(EMonsterState::Patrol));
bIsLosingTarget = false;
}
}
void AMonsterAIController::OnTargetPerceptionUpdated(AActor* Actor, FAIStimulus Stimulus)
{
if (Actor->IsA(ATestPlayerCharacter::StaticClass()))
{
BlackboardComponent = GetBlackboardComponent();
if (Stimulus.WasSuccessfullySensed())
{
LOG(TEXT("[Perception] : %s"), *Actor->GetName());
Blackboard->SetValueAsObject("TargetActor", Actor);
Blackboard->SetValueAsEnum("MonsterState", static_cast<uint8>(EMonsterState::Chase));
}
else
{
// Lost Perception. but Target Value still remains for MaxAge
bIsLosingTarget = true;
LostTargetTime = GetWorld()->GetTimeSeconds(); // Timer On.
}
}
}

EBTNodeResult::Type UBTTask_ChasePlayer::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
.
. // 생략
.
if (Result.Code == EPathFollowingRequestResult::AlreadyAtGoal)
{
// Already Arrived -> State Change
BlackboardComp->SetValueAsEnum("MonsterState", static_cast<uint8>(EMonsterState::Attack));
return EBTNodeResult::Succeeded;
}
else if (Result.Code == EPathFollowingRequestResult::RequestSuccessful)
{
// MonsterState : Chase
return EBTNodeResult::InProgress;
}
else
{
return EBTNodeResult::Failed;
}
}
void UBTTask_ChasePlayer::TickTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
.
. // 생략
.
if (!CachedTargetActor || !IsValid(CachedTargetActor))
{
// Lost TargetActor
FinishLatentTask(*CachedOwnerComp, EBTNodeResult::Failed);
// MonsterAIController handles this processing, but explicitly writes
BlackboardComp->SetValueAsEnum("MonsterState", static_cast<uint8>(EMonsterState::Patrol));
BlackboardComp->ClearValue("TargetActor");
return;
}
if (AIController->GetMoveStatus() == EPathFollowingStatus::Idle)
{
// When it arrives, switch the status to Attack
BlackboardComp->SetValueAsEnum("MonsterState", static_cast<uint8>(EMonsterState::Attack));
FinishLatentTask(*CachedOwnerComp, EBTNodeResult::Succeeded);
}
}
MoveRequest.SetAcceptanceRadius(300.0f);
공격을 제대로 하는 것 같은데 공격하자 마자 다음 문제 발생하면서 에디터 중단
ScriptDelegates.h

계속버튼을 누르니깐 다시 에디터로 돌아오지만 Attack상태에서 Chase, Patrol 상태로 돌아가지 않는 것 같음.
