95 lines
3.2 KiB
C++
95 lines
3.2 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "AI/CombatAIController.h"
|
|
|
|
#include "GameplayTagAssetInterface.h"
|
|
#include "MasterAI.h"
|
|
#include "BehaviorTree/BlackboardComponent.h"
|
|
#include "Components/CombatComponent.h"
|
|
#include "Definitions/CombatGameplayTags.h"
|
|
#include "Perception/AIPerceptionComponent.h"
|
|
#include "Perception/AISenseConfig_Damage.h"
|
|
#include "Perception/AISenseConfig_Sight.h"
|
|
|
|
ACombatAIController::ACombatAIController()
|
|
{
|
|
PerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("PerceptionComponent"));
|
|
|
|
SightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("SightConfig"));
|
|
SightConfig->SightRadius = 3000.f;
|
|
SightConfig->LoseSightRadius = 3500.f;
|
|
SightConfig->PeripheralVisionAngleDegrees = 45.f;
|
|
FAISenseAffiliationFilter AffiliationFilter;
|
|
AffiliationFilter.bDetectEnemies = true;
|
|
AffiliationFilter.bDetectFriendlies = true;
|
|
AffiliationFilter.bDetectNeutrals = true;
|
|
SightConfig->DetectionByAffiliation = AffiliationFilter;
|
|
SightConfig->AutoSuccessRangeFromLastSeenLocation = 2500.f;
|
|
PerceptionComponent->ConfigureSense(*SightConfig);
|
|
|
|
DamageConfig = CreateDefaultSubobject<UAISenseConfig_Damage>(TEXT("DamageConfig"));
|
|
DamageConfig->SetMaxAge(3.f); // Expired 3 Seconds
|
|
PerceptionComponent->ConfigureSense(*DamageConfig);
|
|
|
|
PerceptionComponent->OnPerceptionUpdated.AddDynamic(this, &ACombatAIController::OnUpdatePerception);
|
|
}
|
|
|
|
void ACombatAIController::OnPossess(APawn* InPawn)
|
|
{
|
|
Super::OnPossess(InPawn);
|
|
|
|
AMasterAI* AIpawn = Cast<AMasterAI>(InPawn);
|
|
if(!AIpawn)
|
|
return;
|
|
|
|
MasterAI = AIpawn;
|
|
UCombatComponent* combatComponent = MasterAI->GetComponentByClass<UCombatComponent>();
|
|
combatComponent->OnCombatToggled.AddUObject(this, &ACombatAIController::OnCombatToggle);
|
|
|
|
RunBehaviorTree(MasterAI->GetBeHaviorTree());
|
|
|
|
}
|
|
|
|
void ACombatAIController::OnUpdatePerception(const TArray<AActor*>& PerceivedActors)
|
|
{
|
|
for (auto SensoredActor : PerceivedActors) //탐지된 Actor
|
|
{
|
|
IGameplayTagAssetInterface* CurActor = Cast<IGameplayTagAssetInterface>(SensoredActor); //Player가 아닌 Actor는 탐지되도 반응 없게 함
|
|
if(!CurActor)
|
|
continue;
|
|
if(!CurActor->HasMatchingGameplayTag(FCombatGameplayTags::Get().Character_Player))
|
|
continue;
|
|
|
|
FActorPerceptionBlueprintInfo PerceptionInfo;
|
|
GetPerceptionComponent()->GetActorsPerception(SensoredActor, PerceptionInfo);
|
|
|
|
for(int i = 0; i < PerceptionInfo.LastSensedStimuli.Num(); i++) //탐지방식에 따른 for문
|
|
{
|
|
auto Info = PerceptionInfo.LastSensedStimuli[i];
|
|
auto SensedClass = UAIPerceptionSystem::GetSenseClassForStimulus(this, Info);
|
|
if(SensedClass == UAISense_Sight::StaticClass())
|
|
{
|
|
SetTargetActor(SensoredActor);
|
|
}
|
|
else if(SensedClass == UAISense_Damage::StaticClass())
|
|
{
|
|
if(Info.WasSuccessfullySensed() && !Info.IsExpired()) //After DamageConfig->GetMaxAge then Expired
|
|
SetTargetActor(SensoredActor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ACombatAIController::OnCombatToggle(bool IsCombatEnabled)
|
|
{
|
|
Blackboard->SetValueAsBool(TEXT("bCombatEnabled"), IsCombatEnabled);
|
|
}
|
|
|
|
void ACombatAIController::SetTargetActor(AActor* NewTargetActor)
|
|
{
|
|
Blackboard->SetValueAsObject(TEXT("Target"), NewTargetActor);
|
|
if(IsValid(MasterAI))
|
|
MasterAI->OnTargetSet(NewTargetActor);
|
|
}
|