Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Copyright 2021 Anatoli Kucharau https://vk.com/ulvprog. All Rights Reserved.
- /**
- * Контроллер врага.
- */
- #pragma once
- #include "EnemyAIController.h"
- #include "Kismet/GameplayStatics.h"
- #include "MagicTrigger\Enemy\EnemyCharacterMagicTrigger.h"
- #include "MagicTrigger\Data\DebugMessage.h"
- #include "MagicTrigger\Data\CollisionChannelsMagicTrigger.h"
- #include "UObject/ConstructorHelpers.h"
- #include "Perception/AIPerceptionComponent.h"
- #include "Perception\AISenseConfig_Sight.h"
- #include "Perception\AISenseConfig_Hearing.h"
- #include "BehaviorTree\BehaviorTree.h"
- #include "BehaviorTree\BlackboardData.h"
- #include "BehaviorTree/BehaviorTreeComponent.h"
- #include "BehaviorTree/BlackboardComponent.h"
- #include "NavMesh\RecastNavMesh.h"
- #include "NavAreas\NavArea_Obstacle.h"
- #include "Components\SphereComponent.h"
- class UAISense_Sight;
- AEnemyAIController::AEnemyAIController()
- {
- AIPerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AIPerceptionComponent"));
- AISightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("AISightConfig"));
- AIHearingConfig = CreateDefaultSubobject<UAISenseConfig_Hearing>(TEXT("AIHearingConfig"));
- BlackboardComponent = CreateDefaultSubobject<UBlackboardComponent>(TEXT("BlackboardComponent"));
- BehaviorTreeComponent = CreateDefaultSubobject<UBehaviorTreeComponent>(TEXT("BehaviorTreeComponent"));
- static ConstructorHelpers::FObjectFinder<UBehaviorTree> BTObject(TEXT("/Game/MagicTrigger/AI/Enemy/BT_Enemy"));
- if (BTObject.Succeeded())
- {
- BehaviorTreeAsset = BTObject.Object;
- }
- else
- {
- DEBUGMESSAGE("!BTObject.Succeeded()")
- }
- static ConstructorHelpers::FObjectFinder<UBlackboardData> BBObject(TEXT("/Game/MagicTrigger/AI/Enemy/BB_Enemy"));
- if (BBObject.Succeeded())
- {
- BlackboardAsset = BBObject.Object;
- }
- else
- {
- DEBUGMESSAGE("!BBObject.Succeeded()")
- }
- BBKeys = FBlackboardKeyNamesStruct();
- DeltaAttackRadius = 20;
- BeginPlayTimerTime = 0.2;
- OnPossessTimerTime = 0.2;
- ConfigureAIPerception();
- }
- void AEnemyAIController::BeginPlay()
- {
- Super::BeginPlay();
- StartBeginPlayTimer_IF_Implementation();
- }
- void AEnemyAIController::OnRunAI()
- {
- //DEBUGMESSAGE("OnRunAI");
- this->AIPerceptionComponent->Activate();
- this->BehaviorTreeComponent->StartLogic();
- }
- void AEnemyAIController::OnStopAI()
- {
- //DEBUGMESSAGE("OnStopAI");
- this->AIPerceptionComponent->Deactivate();
- FString Reason;
- this->BehaviorTreeComponent->StopLogic(Reason);
- }
- void AEnemyAIController::OnPossess(APawn* InPawn)
- {
- Super::OnPossess(InPawn);
- if (!GetWorld())
- {
- DEBUGMESSAGE("!GetWorld()");
- return;
- }
- GetWorld()->GetTimerManager().SetTimer(this->OnPossessTimer, this, &AEnemyAIController::CheckReferencesOnPossess, this->OnPossessTimerTime, true);
- }
- void AEnemyAIController::CheckReferencesOnPossess()
- {
- ACharacter* PlayerCharacterTmp;
- AEnemyCharacterMagicTrigger* EnemyTmp;
- PlayerCharacterTmp = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);
- EnemyTmp = GetPawn<AEnemyCharacterMagicTrigger>();
- if (!PlayerCharacterTmp)
- {
- DEBUGMESSAGE("!PlayerCharacter");
- return;
- }
- if (!EnemyTmp)
- {
- DEBUGMESSAGE("!Enemy");
- return;
- }
- this->Enemy = EnemyTmp;
- this->PlayerCharacter = PlayerCharacterTmp;
- GetWorld()->GetTimerManager().ClearTimer(this->OnPossessTimer);
- DoOnPossess();
- }
- void AEnemyAIController::DoOnPossess()
- {
- UAIPerceptionSystem::RegisterPerceptionStimuliSource(GetWorld(), this->AISightConfig->GetSenseImplementation(), this->PlayerCharacter);
- UAIPerceptionSystem::RegisterPerceptionStimuliSource(GetWorld(), this->AIHearingConfig->GetSenseImplementation(), this->PlayerCharacter);
- this->AISightConfig->SightRadius = this->Enemy->EnemyToBehaviorTreeStruct.SightRadius;
- this->AISightConfig->LoseSightRadius = this->Enemy->EnemyToBehaviorTreeStruct.LoseSightRadius;
- this->AIHearingConfig->HearingRange = this->Enemy->EnemyToBehaviorTreeStruct.HearingRange;
- bool bInitializeBB = this->BlackboardComponent->InitializeBlackboard(*this->BlackboardAsset);
- if (!bInitializeBB)
- {
- DEBUGMESSAGE("!bInitializeBB");
- return;
- }
- this->AIPerceptionComponent->OnTargetPerceptionUpdated.AddDynamic(this, &AEnemyAIController::TargetPerceptionUpdate);
- this->BehaviorTreeComponent->StartTree(*this->BehaviorTreeAsset);
- this->AIPerceptionComponent->ProcessStimuli();
- /////////////////////////////////////////////////////////
- /**
- * Поиск перса и останока логики, если перс не найден.
- */
- TSubclassOf<ACharacter> ClassFilter;
- TArray<AActor*> OverlappingActors;
- bool bPlayerCharacterFound = false;
- this->Enemy->RunAISphere->GetOverlappingActors(OverlappingActors, ClassFilter);
- if (!OverlappingActors.Num())
- {
- //DEBUGMESSAGE("!OverlappingActors.Num()")
- OnStopAI();
- }
- else
- {
- for (const auto& OverlappingActor : OverlappingActors)
- {
- ACharacter* OverlappingCharacter = Cast<ACharacter>(OverlappingActor);
- if (OverlappingCharacter == this->PlayerCharacter)
- {
- bPlayerCharacterFound = true;
- break;
- }
- }
- if (!bPlayerCharacterFound)
- {
- //DEBUGMESSAGE("!bPlayerCharacterFound")
- OnStopAI();
- }
- }
- /////////////////////////////////////////////////////////
- }
- void AEnemyAIController::FindPlayer()
- {
- this->Enemy = GetEnemy();
- if (!this->Enemy)
- {
- DEBUGMESSAGE("!this->Enemy");
- return;
- }
- if (!this->BlackboardComponent)
- {
- DEBUGMESSAGE("!this->BlackboardComponent");
- return;
- }
- //DEBUGMESSAGE("FindPlayer");
- this->BlackboardComponent->SetValueAsObject(this->BBKeys.TargetPlayer, this->PlayerCharacter);
- StopMovement();
- this->BlackboardComponent->SetValueAsBool(this->BBKeys.bRoaring, true);
- }
- void AEnemyAIController::LosePlayer()
- {
- if (!this->Enemy)
- {
- DEBUGMESSAGE("!this->Enemy");
- return;
- }
- if (!this->BlackboardComponent)
- {
- DEBUGMESSAGE("!this->BlackboardComponent");
- return;
- }
- if (!this->PlayerCharacter)
- {
- DEBUGMESSAGE("!this->PlayerCharacter");
- return;
- }
- //DEBUGMESSAGE("LosePlayer");
- this->Enemy->StopAttack();
- StopMovement();
- this->BlackboardComponent->ClearValue(this->BBKeys.bCanMoveToPlayer);
- this->BlackboardComponent->ClearValue(this->BBKeys.TargetPlayer);
- this->BlackboardComponent->ClearValue(this->BBKeys.bRoaring);
- this->BlackboardComponent->ClearValue(this->BBKeys.bCanAttack);
- }
- void AEnemyAIController::TargetPerceptionUpdate(AActor* Actor, FAIStimulus Stimulus)
- {
- if (!this->PlayerCharacter)
- {
- //DEBUGMESSAGE("Actor != this->PlayerCharacter");
- return;
- }
- if (Actor != this->PlayerCharacter)
- {
- //DEBUGMESSAGE("Actor != this->PlayerCharacter");
- return;
- }
- UObject* TargetPlayer = this->BlackboardComponent->GetValueAsObject(this->BBKeys.TargetPlayer);
- if (TargetPlayer)
- {
- //DEBUGMESSAGE("TargetPlayer");
- return;
- }
- bool bFindPlayer = Stimulus.WasSuccessfullySensed();
- //DEBUGMESSAGE("TargetPerceptionUpdate");
- if (bFindPlayer)
- {
- //DEBUGMESSAGE("bFindPlayer");
- FindPlayer();
- }
- }
- void AEnemyAIController::ConfigureAIPerception()
- {
- this->AISightConfig->DetectionByAffiliation.bDetectEnemies = true;
- this->AISightConfig->DetectionByAffiliation.bDetectFriendlies = true;
- this->AISightConfig->DetectionByAffiliation.bDetectNeutrals = true;
- this->AIHearingConfig->DetectionByAffiliation.bDetectEnemies = true;
- this->AIHearingConfig->DetectionByAffiliation.bDetectFriendlies = true;
- this->AIHearingConfig->DetectionByAffiliation.bDetectNeutrals = true;
- this->AIPerceptionComponent->ConfigureSense(*this->AISightConfig);
- this->AIPerceptionComponent->ConfigureSense(*this->AIHearingConfig);
- this->AIPerceptionComponent->SetDominantSense(this->AISightConfig->GetSenseImplementation());
- }
- ACharacter* AEnemyAIController::GetPlayerCharacter() const
- {
- if (!this->PlayerCharacter)
- {
- DEBUGMESSAGE("!this->PlayerCharacter");
- }
- return this->PlayerCharacter;
- }
- AEnemyCharacterMagicTrigger* AEnemyAIController::GetEnemy()
- {
- if (!this->Enemy)
- {
- DEBUGMESSAGE("!this->Enemy");
- }
- return this->Enemy;
- }
- void AEnemyAIController::LosePlayer_IF_Implementation()
- {
- LosePlayer();
- }
- /**
- * BeginPlayInterface
- */
- ///////////////////////////////////////////////////////////////////////////////////////
- bool AEnemyAIController::CheckReferences_IF_Implementation()
- {
- UGameplayStatics::GetAllActorsOfClass(GetWorld(), ARecastNavMesh::StaticClass(), this->NavMeshArray);
- if (
- !this->NavMeshArray.Num()
- || !this->NavMeshArray[0]
- || !Cast<ARecastNavMesh>(this->NavMeshArray[0])
- )
- {
- return false;
- }
- return true;
- }
- void AEnemyAIController::DoBeginPlay_IF_Implementation()
- {
- this->NavMesh = Cast<ARecastNavMesh>(this->NavMeshArray[0]);
- }
- void AEnemyAIController::StartBeginPlayTimer_IF_Implementation()
- {
- if (!GetWorld())
- {
- DEBUGMESSAGE("!GetWorld()");
- return;
- }
- GetWorld()->GetTimerManager().SetTimer(this->BeginPlayTimer, this, &AEnemyAIController::BeforeBeginPlay_IF_Implementation, this->BeginPlayTimerTime, true);
- }
- void AEnemyAIController::BeforeBeginPlay_IF_Implementation()
- {
- if (CheckReferences_IF_Implementation())
- {
- GetWorld()->GetTimerManager().ClearTimer(this->BeginPlayTimer);
- DoBeginPlay_IF_Implementation();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement