Add EnemyAIController class

This commit is contained in:
Louis Hobbs 2023-02-03 01:29:38 +00:00
parent 33e0d24d34
commit 7a7f158816
2 changed files with 160 additions and 0 deletions

View File

@ -0,0 +1,112 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "EnemyAIController.h"
#include "Engine/EngineTypes.h"
#include "Components/CapsuleComponent.h"
AEnemyAIController::AEnemyAIController(const FObjectInitializer& object_initializer)
{
Blackboard = CreateDefaultSubobject<UBlackboardComponent>(TEXT("Blackboard"));
BehaviorTree = CreateDefaultSubobject<UBehaviorTreeComponent>(TEXT("Behavior Tree"));
}
void AEnemyAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
auto enemy = Cast<AEnemyCharacter>(InPawn);
check(enemy);
SetPerceptionComponent(*enemy->GetPerceptionComponent());
enemy->GetPerceptionComponent()->OnPerceptionUpdated.AddDynamic(this, &AEnemyAIController::OnPerceptionUpdated);
enemy->GetCharacterMovement()->MaxWalkSpeed = 500.f;
enemy->GetHealthComponent()->OnDamaged.BindUFunction(this, "OnDamaged");
enemy->GetHealthComponent()->OnDeath.BindUFunction(this, "OnDeath");
if (auto behaviourTree = enemy->GetBehaviourTree())
{
Blackboard->InitializeBlackboard(*behaviourTree->BlackboardAsset);
BehaviorTree->StartTree(*behaviourTree);
}
//ensure(enemy->GetMovementComponent()->UseAccelerationForPathFollowing());
}
void AEnemyAIController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
AEnemyCharacter* AEnemyAIController::GetEnemyCharacter()
{
return Cast<AEnemyCharacter>(GetCharacter());
}
void AEnemyAIController::OnDamaged(FDamageInfo info)
{
if (GetEnemyCharacter()->GetHealthComponent()->GetCurrentHealth() > 0.0f)
{
// TODO: Do stuff here
}
}
void AEnemyAIController::OnDeath(FDamageInfo info)
{
// TODO: Do stuff here
auto enemy = GetEnemyCharacter();
enemy->DetachFromControllerPendingDestroy();
enemy->GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
enemy->GetCapsuleComponent()->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
enemy->GetMesh()->SetCollisionProfileName("Ragdoll");
enemy->SetActorEnableCollision(true);
enemy->GetMesh()->SetAllBodiesSimulatePhysics(true);
enemy->GetMesh()->SetSimulatePhysics(true);
enemy->GetMesh()->WakeAllRigidBodies();
enemy->GetMesh()->bBlendPhysics = true;
if (auto characterMovementComponent = enemy->GetCharacterMovement())
{
characterMovementComponent->StopMovementImmediately();
characterMovementComponent->DisableMovement();
characterMovementComponent->SetComponentTickEnabled(false);
}
enemy->SetLifeSpan(10.0f);
}
void AEnemyAIController::OnPerceptionUpdated(const TArray<AActor*>& actors)
{
for (auto actor : actors)
{
if (!actor->GetClass()->IsChildOf(APlayerCharacter::StaticClass()))
{
continue;
}
FActorPerceptionBlueprintInfo perceptionInfo;
GetPerceptionComponent()->GetActorsPerception(actor, perceptionInfo);
for (auto& stimulus : perceptionInfo.LastSensedStimuli)
{
if (!stimulus.IsValid() || stimulus.IsExpired())
{
continue;
}
if (stimulus.IsActive())
{
PlayerCharacter = Cast<APlayerCharacter>(actor);
SetFocus(PlayerCharacter, EAIFocusPriority::Gameplay);
}
else
{
PlayerCharacter = nullptr;
SetFocus(nullptr, EAIFocusPriority::Gameplay);
}
}
}
}

View File

@ -0,0 +1,48 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AIController.h"
#include "BehaviorTree/BehaviorTreeComponent.h"
#include "BehaviorTree/BehaviorTree.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "EnemyCharacter.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "PlayerCharacter.h"
#include "EnemyAIController.generated.h"
/**
*
*/
UCLASS()
class NAKATOMI_API AEnemyAIController : public AAIController
{
GENERATED_BODY()
private:
UBlackboardComponent* Blackboard;
UBehaviorTreeComponent* BehaviorTree;
APlayerCharacter* PlayerCharacter;
public:
AEnemyAIController(const FObjectInitializer& object_initializer);
virtual void OnPossess(APawn* InPawn) override;
virtual void Tick(float DeltaTime) override;
virtual AEnemyCharacter* GetEnemyCharacter();
UFUNCTION()
virtual void OnDamaged(FDamageInfo info);
UFUNCTION()
virtual void OnDeath(FDamageInfo info);
UFUNCTION()
void OnPerceptionUpdated(const TArray<AActor*>& actors);
};