From 418e5a08b770bdb37fdbefd5baaa4385f274ec32 Mon Sep 17 00:00:00 2001 From: "PCYPC\\pcy35" Date: Tue, 29 Aug 2023 20:35:20 +0900 Subject: [PATCH] =?UTF-8?q?[=EB=B0=95=EC=B9=98=EC=98=81]=20Ai=20Perception?= =?UTF-8?q?=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CombatSystem/Blueprints/AI/BB_Base.uasset | Bin 2948 -> 3266 bytes .../Blueprints/AI/BP_ExampleEnemy.uasset | Bin 10110 -> 17085 bytes Source/D1/AI/CombatAIController.cpp | 61 ++++++++++++++++++ Source/D1/AI/CombatAIController.h | 11 +++- Source/D1/AI/MasterAI.cpp | 9 ++- Source/D1/CombatCharacter.cpp | 4 ++ Source/D1/CombatCharacter.h | 13 ++-- Source/D1/Definitions/CombatGameplayTags.cpp | 10 ++- Source/D1/Definitions/CombatGameplayTags.h | 3 + Source/D1/Interface/CombatGameplayTag.cpp | 6 ++ Source/D1/Interface/CombatGameplayTag.h | 27 ++++++++ 11 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 Source/D1/Interface/CombatGameplayTag.cpp create mode 100644 Source/D1/Interface/CombatGameplayTag.h diff --git a/Content/CombatSystem/Blueprints/AI/BB_Base.uasset b/Content/CombatSystem/Blueprints/AI/BB_Base.uasset index ae8141ea5ac751dd22cd715f51530d75cfcfcc26..fefb567b5eec6823f8a3557edf7549fc333c36d1 100644 GIT binary patch delta 602 zcmZuuJ4gdT5S_i;H+K>=ei9+c84F3FL`4LD7$I1t5Vf!{DEO%q5euy~g^flBL{Koc z!4yHkRw_M;jKD z&eot{OqylMJs1WSwf18*j#<^h5mlF7OwQl}QEx<@6IK07$xXrvF_9Or9LJp+XCdrW z{ZhguY%R_@a7yz_DGOJ$p+7yD1K#_5SpWb4 delta 642 zcmX>k*&;r{fMpT~1H)uKW?dl$AW#J2JVp?UfgyrraypNCD1^ztzzSp>01}*FDF%iG z>>wGS7?1|x3qTwdP`^?A<3Z0=ueP(F7Tj&*8oI^E)Hv67#sZG_v)?#0gG>gQqd4(> zu+n#+h5&Am5eV=f2tW=J1`366Z%$!sVch(ksesW?6skrRO8*2Zl!UU8&48<$T)-mF ziQvsZ;T>R+uZPP)P5A*dQ4XJpP`U3wb>eu`$wTEpln8EhObqgq6Ic;Wl%L$eDnI!= ztALmUk|rA_2xk($4k7 zo(~j;sb=N|tL|qv5L1Av1X<$m_Z!u1G;Jh|Dh`V+2Urx!%Tew;$U*~q5?90Og#H9dr?OkI4 diff --git a/Content/CombatSystem/Blueprints/AI/BP_ExampleEnemy.uasset b/Content/CombatSystem/Blueprints/AI/BP_ExampleEnemy.uasset index 908e286e941fa51b0bd1efa77a42fb75a6fcfaa2..9a257ca2025d42afd68ae29492eed59f54d0787a 100644 GIT binary patch literal 17085 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 b&iyz}c}us{YR0F-#bdiS;M^ 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 Q{ERN|zLk)yn*#m+0Qy35X8-^I diff --git a/Source/D1/AI/CombatAIController.cpp b/Source/D1/AI/CombatAIController.cpp index 1e2ba5af..36fbf5a7 100644 --- a/Source/D1/AI/CombatAIController.cpp +++ b/Source/D1/AI/CombatAIController.cpp @@ -3,10 +3,34 @@ #include "AI/CombatAIController.h" +#include "GameplayTagAssetInterface.h" #include "MasterAI.h" +#include "BehaviorTree/BlackboardComponent.h" +#include "Perception/AIPerceptionComponent.h" +#include "Perception/AISenseConfig_Damage.h" +#include "Perception/AISenseConfig_Sight.h" ACombatAIController::ACombatAIController() { + PerceptionComponent = CreateDefaultSubobject(TEXT("PerceptionComponent")); + + SightConfig = CreateDefaultSubobject(TEXT("SightConfig")); + SightConfig->SightRadius = 3000.f; + SightConfig->LoseSightRadius = 3500.f; + SightConfig->PeripheralVisionAngleDegrees = 45.f; + FAISenseAffiliationFilter AffiliationFilter; + AffiliationFilter.bDetectEnemies = true; + AffiliationFilter.bDetectFriendlies = true; + AffiliationFilter.bDetectNeutrals = true; + SightConfig->DetectionByAffiliation = AffiliationFilter; + SightConfig->AutoSuccessRangeFromLastSeenLocation = 500.f; + PerceptionComponent->ConfigureSense(*SightConfig); + + DamageConfig = CreateDefaultSubobject(TEXT("DamageConfig")); + DamageConfig->SetMaxAge(3.f); // Expired 3 Seconds + PerceptionComponent->ConfigureSense(*DamageConfig); + + PerceptionComponent->OnPerceptionUpdated.AddDynamic(this, &ACombatAIController::OnUpdatePerception); } void ACombatAIController::OnPossess(APawn* InPawn) @@ -20,3 +44,40 @@ void ACombatAIController::OnPossess(APawn* InPawn) RunBehaviorTree(MasterAI->GetBeHaviorTree()); } } + +void ACombatAIController::OnUpdatePerception(const TArray& PerceivedActors) +{ + for (auto SensoredActor : PerceivedActors) + { + FActorPerceptionBlueprintInfo PerceptionInfo; + GetPerceptionComponent()->GetActorsPerception(SensoredActor, PerceptionInfo); + + for(int i = 0; i < PerceptionInfo.LastSensedStimuli.Num(); i++) + { + auto Info = PerceptionInfo.LastSensedStimuli[i]; + auto SensedClass = UAIPerceptionSystem::GetSenseClassForStimulus(this, Info); + if(SensedClass == UAISense_Sight::StaticClass()) + { + if(Info.WasSuccessfullySensed()) + { + if(Cast(SensoredActor)->HasMatchingGameplayTag(FCombatGameplayTags::Get().Character_Player)) + { + Blackboard->SetValueAsObject(TEXT("Target"), SensoredActor); + } + } + else + Blackboard->SetValueAsObject(TEXT("Target"), nullptr); + } + else if(SensedClass == UAISense_Damage::StaticClass()) + { + if(Info.WasSuccessfullySensed() && !Info.IsExpired()) //After DamageConfig->GetMaxAge then Expired + { + if(Cast(SensoredActor)->HasMatchingGameplayTag(FCombatGameplayTags::Get().Character_Player)) + { + Blackboard->SetValueAsObject(TEXT("Target"), SensoredActor); + } + } + } + } + } +} diff --git a/Source/D1/AI/CombatAIController.h b/Source/D1/AI/CombatAIController.h index f8b04472..a56b30ab 100644 --- a/Source/D1/AI/CombatAIController.h +++ b/Source/D1/AI/CombatAIController.h @@ -16,9 +16,16 @@ class D1_API ACombatAIController : public AAIController public: ACombatAIController(); - -protected: +protected: //Inherited Func virtual void OnPossess(APawn* InPawn) override; +public: //Delegate Func + UFUNCTION(BlueprintCallable) + void OnUpdatePerception(const TArray& PerceivedActors); private: + UPROPERTY() TObjectPtr MasterAI; + UPROPERTY() + TObjectPtr SightConfig; + UPROPERTY() + TObjectPtr DamageConfig; }; diff --git a/Source/D1/AI/MasterAI.cpp b/Source/D1/AI/MasterAI.cpp index d9376115..51aeb81a 100644 --- a/Source/D1/AI/MasterAI.cpp +++ b/Source/D1/AI/MasterAI.cpp @@ -16,6 +16,7 @@ #include "DamageType/AttackDamageType.h" #include "Kismet/KismetMathLibrary.h" #include "Kismet/GameplayStatics.h" +#include "Perception/AISense_Damage.h" AMasterAI::AMasterAI() { @@ -98,12 +99,16 @@ float AMasterAI::TakeDamage(float Damage, FDamageEvent const& DamageEvent, ACont if (DamageEvent.IsOfType(FPointDamageEvent::ClassID)) { const FPointDamageEvent* PointDamageEvent = static_cast(&DamageEvent); - + APawn* Attacker = EventInstigator->GetPawn(); + //스텟 관련 처리 StatsComponent->TakeDamageOnStat(Damage); + //데미지 관련 AI 처리 + UAISense_Damage::ReportDamageEvent(GetWorld(), this, Attacker, Damage, PointDamageEvent->HitInfo.Location, PointDamageEvent->HitInfo.Location); + //앞에서 맞았는지 뒤에서 맞았는지 판별 - bHitFront = UKismetMathLibrary::InRange_FloatFloat(this->GetDotProductTo(EventInstigator->GetPawn()), -0.1f, 1.f); + bHitFront = UKismetMathLibrary::InRange_FloatFloat(this->GetDotProductTo(Attacker), -0.1f, 1.f); LastHitInfo = PointDamageEvent->HitInfo; //play sound, effect diff --git a/Source/D1/CombatCharacter.cpp b/Source/D1/CombatCharacter.cpp index ce709372..48e4b1e8 100644 --- a/Source/D1/CombatCharacter.cpp +++ b/Source/D1/CombatCharacter.cpp @@ -92,8 +92,12 @@ ACombatCharacter::ACombatCharacter() JoggingSpeed = 500.f; SprintSpeed = 700.f; + //Settings OwnedGameplayTags + OwnedGameplayTags.AddTag(FCombatGameplayTags::Get().Character_Player); + ChargeAttackTime = 0.18f; PelvisBoneName = TEXT("pelvis"); + } void ACombatCharacter::BeginPlay() diff --git a/Source/D1/CombatCharacter.h b/Source/D1/CombatCharacter.h index 072d969c..4a921388 100644 --- a/Source/D1/CombatCharacter.h +++ b/Source/D1/CombatCharacter.h @@ -3,6 +3,7 @@ #pragma once #include "CoreMinimal.h" +#include "GameplayTagAssetInterface.h" #include "GameFramework/Character.h" #include "InputActionValue.h" #include "InputAction.h" @@ -11,11 +12,12 @@ #include "Components/StatsComponent.h" #include "Components/TargetingComponent.h" #include "Definitions/GameEnums.h" +#include "Interface/CombatGameplayTag.h" #include "CombatCharacter.generated.h" UCLASS(config=Game) -class ACombatCharacter : public ACharacter, public ICombatInterface +class ACombatCharacter : public ACharacter, public ICombatInterface, public IGameplayTagAssetInterface { GENERATED_BODY() @@ -108,7 +110,9 @@ public: virtual void SetCanMove_Implementation(bool inputCanMove) override; virtual EMovementSpeedMode GetCombatMovementSpeedMode() override { return GetMovementSpeedMode(); } - + + // Inherited via IGameplayTagAssetInterface + virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override { TagContainer = OwnedGameplayTags; } public: void SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode); FORCEINLINE EMovementSpeedMode GetMovementSpeedMode() const { return MovementSpeedMode; } @@ -206,12 +210,13 @@ public: private: FTimerHandle StaminaTimerHandle; - + private: bool IsHeavyAttack; float AttackHeldTime; bool bAttackCharged; bool bCanMove = true; bool bHitFront; - FHitResult LastHitInfo; + FHitResult LastHitInfo; + FGameplayTagContainer OwnedGameplayTags; }; diff --git a/Source/D1/Definitions/CombatGameplayTags.cpp b/Source/D1/Definitions/CombatGameplayTags.cpp index 2c9938c5..c170d0cc 100644 --- a/Source/D1/Definitions/CombatGameplayTags.cpp +++ b/Source/D1/Definitions/CombatGameplayTags.cpp @@ -8,8 +8,16 @@ FCombatGameplayTags FCombatGameplayTags::GameplayTags; void FCombatGameplayTags::InitializeNativeGameplayTags() { - if(GameplayTags.Character_State_Attacking.IsValid()) //Already Execute? then Do not Execute + if(GameplayTags.Character_Player.IsValid()) //Already Execute? then Do not Execute return; + + /** + * Player + */ + GameplayTags.Character_Player = UGameplayTagsManager::Get().AddNativeGameplayTag( + FName("Character.Player"), + FString("Player") + ); /** * State diff --git a/Source/D1/Definitions/CombatGameplayTags.h b/Source/D1/Definitions/CombatGameplayTags.h index a2fe3941..f898203e 100644 --- a/Source/D1/Definitions/CombatGameplayTags.h +++ b/Source/D1/Definitions/CombatGameplayTags.h @@ -12,6 +12,9 @@ public: static void InitializeNativeGameplayTags(); public: + //Character + FGameplayTag Character_Player; + //State FGameplayTag Character_State_Attacking; FGameplayTag Character_State_Dead; diff --git a/Source/D1/Interface/CombatGameplayTag.cpp b/Source/D1/Interface/CombatGameplayTag.cpp new file mode 100644 index 00000000..29c2e6e3 --- /dev/null +++ b/Source/D1/Interface/CombatGameplayTag.cpp @@ -0,0 +1,6 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Interface/CombatGameplayTag.h" + +// Add default functionality here for any ICombatGameplayTag functions that are not pure virtual. diff --git a/Source/D1/Interface/CombatGameplayTag.h b/Source/D1/Interface/CombatGameplayTag.h new file mode 100644 index 00000000..cc60f8d5 --- /dev/null +++ b/Source/D1/Interface/CombatGameplayTag.h @@ -0,0 +1,27 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameplayTagContainer.h" +#include "UObject/Interface.h" +#include "CombatGameplayTag.generated.h" + +// This class does not need to be modified. +UINTERFACE(MinimalAPI) +class UCombatGameplayTag : public UInterface +{ + GENERATED_BODY() +}; + +/** + * + */ +class D1_API ICombatGameplayTag +{ + GENERATED_BODY() + + // Add interface functions to this class. This is the class that will be inherited to implement this interface. +public: + virtual FGameplayTagContainer GetOwnedGameplayTag() = 0; +};