Add EnemyAIController class
This commit is contained in:
parent
33e0d24d34
commit
7a7f158816
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
};
|
Loading…
Reference in New Issue