From 44e25b8472dfee24766b1d1ebb6d6a8849e40d26 Mon Sep 17 00:00:00 2001 From: PHILIP WHITE Date: Wed, 4 Oct 2023 02:25:27 +0100 Subject: [PATCH] Add Companion Character for Generic Base --- EndlessVendetta/Content/AI/EQSB_Enemy.uasset | 3 + EndlessVendetta/Content/AI/EQSB_Player.uasset | 3 + EndlessVendetta/Content/AI/EQS_Test.uasset | 3 + .../Content/AI/Enemy/Basic/EQSB_Enemy.uasset | 3 - .../Content/AI/Enemy/Basic/EQSB_Player.uasset | 3 - .../AI/Enemy/Basic/EQS_EnemyFindCover.uasset | 4 +- .../Content/AI/Enemy/Basic/EQS_Test.uasset | 3 - .../B/AZ/GX8EY01G00J28SE17R0FJV.uasset | 4 +- .../E/PJ/BY6E8JXZSRNMAW3DFHRHRJ.uasset | 4 +- .../AI/AI_CompanionController.cpp | 85 +++++++++++++++++++ .../AI/AI_CompanionController.h | 36 ++++++++ .../EndlessVendetta/AI/AI_EnemyController.cpp | 2 +- .../EndlessVendetta/AI/CompanionCharacter.cpp | 50 +++++++++++ .../EndlessVendetta/AI/CompanionCharacter.h | 38 +++++++++ 14 files changed, 225 insertions(+), 16 deletions(-) create mode 100644 EndlessVendetta/Content/AI/EQSB_Enemy.uasset create mode 100644 EndlessVendetta/Content/AI/EQSB_Player.uasset create mode 100644 EndlessVendetta/Content/AI/EQS_Test.uasset delete mode 100644 EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Enemy.uasset delete mode 100644 EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Player.uasset delete mode 100644 EndlessVendetta/Content/AI/Enemy/Basic/EQS_Test.uasset create mode 100644 EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.h create mode 100644 EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.cpp create mode 100644 EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.h diff --git a/EndlessVendetta/Content/AI/EQSB_Enemy.uasset b/EndlessVendetta/Content/AI/EQSB_Enemy.uasset new file mode 100644 index 00000000..39744dd3 --- /dev/null +++ b/EndlessVendetta/Content/AI/EQSB_Enemy.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9fafb5ea724311d8a706eb8f12493e004ab343735895a80be1811e2caa95f64 +size 18966 diff --git a/EndlessVendetta/Content/AI/EQSB_Player.uasset b/EndlessVendetta/Content/AI/EQSB_Player.uasset new file mode 100644 index 00000000..65abdba4 --- /dev/null +++ b/EndlessVendetta/Content/AI/EQSB_Player.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92ebb9e1566806ef68b6d274fa0a1ebd629b71d24c87c36024db0720213cdc8b +size 17638 diff --git a/EndlessVendetta/Content/AI/EQS_Test.uasset b/EndlessVendetta/Content/AI/EQS_Test.uasset new file mode 100644 index 00000000..d6184a2f --- /dev/null +++ b/EndlessVendetta/Content/AI/EQS_Test.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d7fcae1638292db5530edb7c1a864ecfedc45f339b8bbf85f86a78754f1ac4a +size 24150 diff --git a/EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Enemy.uasset b/EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Enemy.uasset deleted file mode 100644 index 436112d7..00000000 --- a/EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Enemy.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:978aab3035ae3876cef293be990751ff0a4966d407f62262698a530862855320 -size 19419 diff --git a/EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Player.uasset b/EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Player.uasset deleted file mode 100644 index a1e8f59b..00000000 --- a/EndlessVendetta/Content/AI/Enemy/Basic/EQSB_Player.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4da78b93d151ff916a8b62f09f88ce28b8efeb76a9d1d468a6e56f95d50a711d -size 17987 diff --git a/EndlessVendetta/Content/AI/Enemy/Basic/EQS_EnemyFindCover.uasset b/EndlessVendetta/Content/AI/Enemy/Basic/EQS_EnemyFindCover.uasset index d8fa1226..ae3f1455 100644 --- a/EndlessVendetta/Content/AI/Enemy/Basic/EQS_EnemyFindCover.uasset +++ b/EndlessVendetta/Content/AI/Enemy/Basic/EQS_EnemyFindCover.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:115f268dcbca6bf144baa4bb0572ea023da1ffd074ae6e7dd445bd9f4cba645c -size 11772 +oid sha256:9e53cfdf2c62f71a8e9cf4533df7a333c33ddec1b9b830b7c85434c2dad50b3c +size 11760 diff --git a/EndlessVendetta/Content/AI/Enemy/Basic/EQS_Test.uasset b/EndlessVendetta/Content/AI/Enemy/Basic/EQS_Test.uasset deleted file mode 100644 index eb8c4663..00000000 --- a/EndlessVendetta/Content/AI/Enemy/Basic/EQS_Test.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5f5b2ddf1641fad4bf9b75104089070dd382ab3b630619aa5cbb0fb19e215f22 -size 22729 diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/B/AZ/GX8EY01G00J28SE17R0FJV.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/B/AZ/GX8EY01G00J28SE17R0FJV.uasset index 60451f7e..b1ec8842 100644 --- a/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/B/AZ/GX8EY01G00J28SE17R0FJV.uasset +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/B/AZ/GX8EY01G00J28SE17R0FJV.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7cb8357ffc004ebe77fee2fef237bde524e9a64befca078884785e9762c654c -size 5440 +oid sha256:b846a25931a6e0277f004c0f41c52eb17b7ea951697783592186c6cb01904bfc +size 5216 diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/E/PJ/BY6E8JXZSRNMAW3DFHRHRJ.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/E/PJ/BY6E8JXZSRNMAW3DFHRHRJ.uasset index 93f0eeb7..4abdf431 100644 --- a/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/E/PJ/BY6E8JXZSRNMAW3DFHRHRJ.uasset +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/EnemyAITest/E/PJ/BY6E8JXZSRNMAW3DFHRHRJ.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7b6617a297705f0f5de3dd5a3a85b65bb6984399bbacc3863b84e88df64cd01e -size 5115 +oid sha256:cfb0f1718ab71a979c83b7884652cb8b9a757abf7c2e17c1d3b356f1ef4228f7 +size 5313 diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.cpp new file mode 100644 index 00000000..5ca23fe3 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.cpp @@ -0,0 +1,85 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AI_CompanionController.h" + +#include "AI_EnemyController.h" +#include "CompanionCharacter.h" +#include "EndlessVendetta/EndlessVendettaCharacter.h" +#include "Perception/AIPerceptionComponent.h" +#include "Perception/AISenseConfig_Sight.h" + + +AAI_CompanionController::AAI_CompanionController(FObjectInitializer const& ObjectInitializer) +{ + // 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; + AAIController::SetGenericTeamId(FGenericTeamId(0)); + SetupPerceptionSystem(); +} + +// Called when the game starts or when spawned +void AAI_CompanionController::BeginPlay() +{ + Super::BeginPlay(); +} + +void AAI_CompanionController::OnPossess(APawn* InPawn) +{ + Super::OnPossess(InPawn); + if (const ACompanionCharacter* CompanionCharacter = Cast(InPawn)) + { + if (UBehaviorTree* const BehaviorTree = CompanionCharacter->GetBehaviorTree()) + { + UBlackboardComponent* TempBlackboardPtr; + UseBlackboard(BehaviorTree->BlackboardAsset, TempBlackboardPtr); + Blackboard = TempBlackboardPtr; + RunBehaviorTree(BehaviorTree); + } + } +} + +// Called every frame +void AAI_CompanionController::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + +void AAI_CompanionController::SetupPerceptionSystem() +{ + SightConfig = CreateDefaultSubobject(TEXT("Sight Config")); + if (IsValid(SightConfig)) + { + SetPerceptionComponent(*CreateDefaultSubobject(TEXT("Perception Component"))); + SightConfig->SightRadius = 2000.0f; + SightConfig->LoseSightRadius = 2100.0f; + SightConfig->PeripheralVisionAngleDegrees = 70.0f; + SightConfig->SetMaxAge(20.0f); + SightConfig->AutoSuccessRangeFromLastSeenLocation = 520.0f; + SightConfig->DetectionByAffiliation.bDetectEnemies = true; + SightConfig->DetectionByAffiliation.bDetectFriendlies = true; + SightConfig->DetectionByAffiliation.bDetectNeutrals = true; + GetPerceptionComponent()->SetDominantSense(*SightConfig->GetSenseImplementation()); + GetPerceptionComponent()->OnTargetPerceptionUpdated.AddDynamic(this, &AAI_CompanionController::OnTargetPerceptionUpdated); + GetPerceptionComponent()->ConfigureSense(*SightConfig); + } +} + +void AAI_CompanionController::OnTargetPerceptionUpdated(AActor* Actor, FAIStimulus const Stimulus) +{ + if (AEndlessVendettaCharacter* const PlayerCharacter = Cast(Actor)) + { + // if (Stimulus.WasSuccessfullySensed()) + // { + // GetBlackboardComponent()->SetValueAsObject("TargetPlayer", Actor); + // GetBlackboardComponent()->SetValueAsVector("TargetLocation", Stimulus.StimulusLocation); + // GetBlackboardComponent()->SetValueAsBool("CanSeePlayer", true); + // } + // else + // { + // GetBlackboardComponent()->ClearValue("TargetActor"); + // GetBlackboardComponent()->ClearValue("TargetLocation"); + // GetBlackboardComponent()->SetValueAsBool("CanSeePlayer", false); + // } + } +} diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.h b/EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.h new file mode 100644 index 00000000..3fb57dc2 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_CompanionController.h @@ -0,0 +1,36 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "AIController.h" +#include "AI_CompanionController.generated.h" + +struct FAIStimulus; + +UCLASS() +class ENDLESSVENDETTA_API AAI_CompanionController : public AAIController +{ + GENERATED_BODY() + +public: + // Sets default values for this actor's properties + explicit AAI_CompanionController(FObjectInitializer const& ObjectInitializer); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + virtual void OnPossess(APawn* InPawn) override; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; + +private: + class UAISenseConfig_Sight* SightConfig; + void SetupPerceptionSystem(); + + UFUNCTION() + void OnTargetPerceptionUpdated(AActor* Actor, FAIStimulus const Stimulus); + +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.cpp index 6e0b0ec2..f29f3d4a 100644 --- a/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_EnemyController.cpp @@ -15,7 +15,7 @@ AAI_EnemyController::AAI_EnemyController(FObjectInitializer const& ObjectInitial { // 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; - SetGenericTeamId(FGenericTeamId(1)); + AAIController::SetGenericTeamId(FGenericTeamId(1)); SetupPerceptionSystem(); } diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.cpp new file mode 100644 index 00000000..5475ee04 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.cpp @@ -0,0 +1,50 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "CompanionCharacter.h" + +#include "Perception/AIPerceptionStimuliSourceComponent.h" +#include "Perception/AISense_Sight.h" + + +// Sets default values +ACompanionCharacter::ACompanionCharacter() +{ + // Set this character 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 ACompanionCharacter::BeginPlay() +{ + Super::BeginPlay(); + +} + +// Called every frame +void ACompanionCharacter::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + +// Called to bind functionality to input +void ACompanionCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) +{ + Super::SetupPlayerInputComponent(PlayerInputComponent); +} + +UBehaviorTree* ACompanionCharacter::GetBehaviorTree() const +{ + return BehaviorTree; +} + +void ACompanionCharacter::SetupStimuliSourceComponent() +{ + StimuliSourceComponent = CreateDefaultSubobject(TEXT("Stimuli Source Component")); + if (IsValid(StimuliSourceComponent)) + { + StimuliSourceComponent->RegisterForSense(TSubclassOf()); + StimuliSourceComponent->RegisterWithPerceptionSystem(); + } +} + diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.h b/EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.h new file mode 100644 index 00000000..0a484bbc --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/CompanionCharacter.h @@ -0,0 +1,38 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "BehaviorTree/BehaviorTree.h" +#include "GameFramework/Character.h" +#include "CompanionCharacter.generated.h" + +UCLASS() +class ENDLESSVENDETTA_API ACompanionCharacter : public ACharacter +{ + GENERATED_BODY() + +public: + // Sets default values for this character's properties + ACompanionCharacter(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AI") + UBehaviorTree* BehaviorTree; +public: + // Called every frame + virtual void Tick(float DeltaTime) override; + + // Called to bind functionality to input + virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; + + UFUNCTION(BlueprintCallable, Category = "AI") + UBehaviorTree* GetBehaviorTree() const; + +private: + class UAIPerceptionStimuliSourceComponent* StimuliSourceComponent; + void SetupStimuliSourceComponent(); +};