From 13e86b5288637db72779f5475c36b0310568d520 Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Mon, 9 Oct 2023 03:35:42 +0100 Subject: [PATCH] Add AIControlHub for AI Alert Level Synchronisation --- .../AI/Enemy/Basic/BP_AIControlHub.uasset | 3 + .../EndlessVendetta/AI/AIControlHub.cpp | 59 +++++++++++++++++++ .../Source/EndlessVendetta/AI/AIControlHub.h | 41 +++++++++++++ .../EndlessVendetta/AI/AI_EnemyController.h | 3 +- .../EndlessVendetta/AI/EnemyCharacter.cpp | 14 +++++ .../EndlessVendetta/AI/EnemyCharacter.h | 5 ++ 6 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 EndlessVendetta/Content/AI/Enemy/Basic/BP_AIControlHub.uasset create mode 100644 EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.h diff --git a/EndlessVendetta/Content/AI/Enemy/Basic/BP_AIControlHub.uasset b/EndlessVendetta/Content/AI/Enemy/Basic/BP_AIControlHub.uasset new file mode 100644 index 00000000..22898b43 --- /dev/null +++ b/EndlessVendetta/Content/AI/Enemy/Basic/BP_AIControlHub.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef50faf065f81655d520a752397bdbba2865e4c96e537947d4cdd3c78508f1e6 +size 21271 diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.cpp new file mode 100644 index 00000000..688ede79 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.cpp @@ -0,0 +1,59 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AIControlHub.h" + +#include "EnemyCharacter.h" + + +// Sets default values +AAIControlHub::AAIControlHub() +{ + // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; +} + +// Called when the game starts or when spawned +void AAIControlHub::BeginPlay() +{ + Super::BeginPlay(); + + for (AEnemyCharacter* EnemyActor : EnemyActors) + { + EnemyActor->SubscribeToAlertLevelEvent(this); + } +} + +// Called every frame +void AAIControlHub::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + +void AAIControlHub::IncreaseAlertLevel() +{ + AlertLevel = FMath::Clamp(AlertLevel + 1, 0, 3); + OnAlertLevelChanged(); +} + +void AAIControlHub::DecreaseAlertLevel() +{ + AlertLevel = FMath::Clamp(AlertLevel - 1, 0, 3); + OnAlertLevelChanged(); +} + +void AAIControlHub::SetAlertLevel(int NewAlertLevel) +{ + AlertLevel = FMath::Clamp(NewAlertLevel, 0, 3); + OnAlertLevelChanged(); +} + +int AAIControlHub::GetAlertLevel() const +{ + return AlertLevel; +} + +void AAIControlHub::OnAlertLevelChanged() const +{ + AlertLevelEvent.Broadcast(AlertLevel); +} diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.h b/EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.h new file mode 100644 index 00000000..95a84534 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AIControlHub.h @@ -0,0 +1,41 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "EnemyCharacter.h" +#include "GameFramework/Actor.h" +#include "AIControlHub.generated.h" + +UCLASS() +class ENDLESSVENDETTA_API AAIControlHub : public AActor +{ + GENERATED_BODY() + +public: + // Sets default values for this actor's properties + AAIControlHub(); + + DECLARE_EVENT_OneParam(AAI_EnemyController, FAlertLevelEvent, int); + FAlertLevelEvent AlertLevelEvent; + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; + + void IncreaseAlertLevel(); + void DecreaseAlertLevel(); + void SetAlertLevel(int NewAlertLevel); + int GetAlertLevel() const; + void OnAlertLevelChanged() const; + +private: + int AlertLevel = 0; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AI", meta = (AllowPrivateAccess = "true")) + TArray EnemyActors; +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.h b/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.h index c17469a2..ae91c3f4 100644 --- a/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.h +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.h @@ -26,11 +26,12 @@ public: virtual void Tick(float DeltaTime) override; private: + UPROPERTY() class UAISenseConfig_Sight* SightConfig; + UPROPERTY() class UAISenseConfig_Hearing* HearingConfig; void SetupPerceptionSystem(); UFUNCTION() void OnTargetPerceptionUpdated(AActor* Actor, FAIStimulus const Stimulus); - }; diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp index 72f9fabb..e971fab8 100644 --- a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp @@ -3,6 +3,10 @@ #include "EnemyCharacter.h" +#include "AIControlHub.h" +#include "AIController.h" +#include "BehaviorTree/BlackboardComponent.h" + class UAISense_Sight; // Sets default values @@ -24,3 +28,13 @@ void AEnemyCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); } + +void AEnemyCharacter::SubscribeToAlertLevelEvent(AAIControlHub* ControlHub) +{ + AlertLevelDelegateHandle = ControlHub->AlertLevelEvent.AddUObject(this, &AEnemyCharacter::SetAlertLevel); +} + +void AEnemyCharacter::SetAlertLevel(const int NewAlertLevel) const +{ + Cast(GetController())->GetBlackboardComponent()->SetValueAsInt("AlertLevel", NewAlertLevel); +} diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h index 6c6cfebe..7a0278e6 100644 --- a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h +++ b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h @@ -24,4 +24,9 @@ protected: public: // Called every frame virtual void Tick(float DeltaTime) override; + void SubscribeToAlertLevelEvent(class AAIControlHub* ControlHub); + +private: + FDelegateHandle AlertLevelDelegateHandle; + void SetAlertLevel(int NewAlertLevel) const; };