[박치영] Ai Perception 작업
parent
c42582a55c
commit
418e5a08b7
Binary file not shown.
Binary file not shown.
|
|
@ -3,10 +3,34 @@
|
||||||
|
|
||||||
#include "AI/CombatAIController.h"
|
#include "AI/CombatAIController.h"
|
||||||
|
|
||||||
|
#include "GameplayTagAssetInterface.h"
|
||||||
#include "MasterAI.h"
|
#include "MasterAI.h"
|
||||||
|
#include "BehaviorTree/BlackboardComponent.h"
|
||||||
|
#include "Perception/AIPerceptionComponent.h"
|
||||||
|
#include "Perception/AISenseConfig_Damage.h"
|
||||||
|
#include "Perception/AISenseConfig_Sight.h"
|
||||||
|
|
||||||
ACombatAIController::ACombatAIController()
|
ACombatAIController::ACombatAIController()
|
||||||
{
|
{
|
||||||
|
PerceptionComponent = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("PerceptionComponent"));
|
||||||
|
|
||||||
|
SightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(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<UAISenseConfig_Damage>(TEXT("DamageConfig"));
|
||||||
|
DamageConfig->SetMaxAge(3.f); // Expired 3 Seconds
|
||||||
|
PerceptionComponent->ConfigureSense(*DamageConfig);
|
||||||
|
|
||||||
|
PerceptionComponent->OnPerceptionUpdated.AddDynamic(this, &ACombatAIController::OnUpdatePerception);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACombatAIController::OnPossess(APawn* InPawn)
|
void ACombatAIController::OnPossess(APawn* InPawn)
|
||||||
|
|
@ -20,3 +44,40 @@ void ACombatAIController::OnPossess(APawn* InPawn)
|
||||||
RunBehaviorTree(MasterAI->GetBeHaviorTree());
|
RunBehaviorTree(MasterAI->GetBeHaviorTree());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ACombatAIController::OnUpdatePerception(const TArray<AActor*>& 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<IGameplayTagAssetInterface>(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<IGameplayTagAssetInterface>(SensoredActor)->HasMatchingGameplayTag(FCombatGameplayTags::Get().Character_Player))
|
||||||
|
{
|
||||||
|
Blackboard->SetValueAsObject(TEXT("Target"), SensoredActor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,16 @@ class D1_API ACombatAIController : public AAIController
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ACombatAIController();
|
ACombatAIController();
|
||||||
|
protected: //Inherited Func
|
||||||
protected:
|
|
||||||
virtual void OnPossess(APawn* InPawn) override;
|
virtual void OnPossess(APawn* InPawn) override;
|
||||||
|
public: //Delegate Func
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void OnUpdatePerception(const TArray<AActor*>& PerceivedActors);
|
||||||
private:
|
private:
|
||||||
|
UPROPERTY()
|
||||||
TObjectPtr<class AMasterAI> MasterAI;
|
TObjectPtr<class AMasterAI> MasterAI;
|
||||||
|
UPROPERTY()
|
||||||
|
TObjectPtr<class UAISenseConfig_Sight> SightConfig;
|
||||||
|
UPROPERTY()
|
||||||
|
TObjectPtr<class UAISenseConfig_Damage> DamageConfig;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "DamageType/AttackDamageType.h"
|
#include "DamageType/AttackDamageType.h"
|
||||||
#include "Kismet/KismetMathLibrary.h"
|
#include "Kismet/KismetMathLibrary.h"
|
||||||
#include "Kismet/GameplayStatics.h"
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
#include "Perception/AISense_Damage.h"
|
||||||
|
|
||||||
AMasterAI::AMasterAI()
|
AMasterAI::AMasterAI()
|
||||||
{
|
{
|
||||||
|
|
@ -98,12 +99,16 @@ float AMasterAI::TakeDamage(float Damage, FDamageEvent const& DamageEvent, ACont
|
||||||
if (DamageEvent.IsOfType(FPointDamageEvent::ClassID))
|
if (DamageEvent.IsOfType(FPointDamageEvent::ClassID))
|
||||||
{
|
{
|
||||||
const FPointDamageEvent* PointDamageEvent = static_cast<const FPointDamageEvent*>(&DamageEvent);
|
const FPointDamageEvent* PointDamageEvent = static_cast<const FPointDamageEvent*>(&DamageEvent);
|
||||||
|
APawn* Attacker = EventInstigator->GetPawn();
|
||||||
|
|
||||||
//스텟 관련 처리
|
//스텟 관련 처리
|
||||||
StatsComponent->TakeDamageOnStat(Damage);
|
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;
|
LastHitInfo = PointDamageEvent->HitInfo;
|
||||||
|
|
||||||
//play sound, effect
|
//play sound, effect
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,12 @@ ACombatCharacter::ACombatCharacter()
|
||||||
JoggingSpeed = 500.f;
|
JoggingSpeed = 500.f;
|
||||||
SprintSpeed = 700.f;
|
SprintSpeed = 700.f;
|
||||||
|
|
||||||
|
//Settings OwnedGameplayTags
|
||||||
|
OwnedGameplayTags.AddTag(FCombatGameplayTags::Get().Character_Player);
|
||||||
|
|
||||||
ChargeAttackTime = 0.18f;
|
ChargeAttackTime = 0.18f;
|
||||||
PelvisBoneName = TEXT("pelvis");
|
PelvisBoneName = TEXT("pelvis");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACombatCharacter::BeginPlay()
|
void ACombatCharacter::BeginPlay()
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameplayTagAssetInterface.h"
|
||||||
#include "GameFramework/Character.h"
|
#include "GameFramework/Character.h"
|
||||||
#include "InputActionValue.h"
|
#include "InputActionValue.h"
|
||||||
#include "InputAction.h"
|
#include "InputAction.h"
|
||||||
|
|
@ -11,11 +12,12 @@
|
||||||
#include "Components/StatsComponent.h"
|
#include "Components/StatsComponent.h"
|
||||||
#include "Components/TargetingComponent.h"
|
#include "Components/TargetingComponent.h"
|
||||||
#include "Definitions/GameEnums.h"
|
#include "Definitions/GameEnums.h"
|
||||||
|
#include "Interface/CombatGameplayTag.h"
|
||||||
#include "CombatCharacter.generated.h"
|
#include "CombatCharacter.generated.h"
|
||||||
|
|
||||||
|
|
||||||
UCLASS(config=Game)
|
UCLASS(config=Game)
|
||||||
class ACombatCharacter : public ACharacter, public ICombatInterface
|
class ACombatCharacter : public ACharacter, public ICombatInterface, public IGameplayTagAssetInterface
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
|
@ -108,7 +110,9 @@ public:
|
||||||
virtual void SetCanMove_Implementation(bool inputCanMove) override;
|
virtual void SetCanMove_Implementation(bool inputCanMove) override;
|
||||||
|
|
||||||
virtual EMovementSpeedMode GetCombatMovementSpeedMode() override { return GetMovementSpeedMode(); }
|
virtual EMovementSpeedMode GetCombatMovementSpeedMode() override { return GetMovementSpeedMode(); }
|
||||||
|
|
||||||
|
// Inherited via IGameplayTagAssetInterface
|
||||||
|
virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override { TagContainer = OwnedGameplayTags; }
|
||||||
public:
|
public:
|
||||||
void SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode);
|
void SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode);
|
||||||
FORCEINLINE EMovementSpeedMode GetMovementSpeedMode() const { return MovementSpeedMode; }
|
FORCEINLINE EMovementSpeedMode GetMovementSpeedMode() const { return MovementSpeedMode; }
|
||||||
|
|
@ -206,12 +210,13 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FTimerHandle StaminaTimerHandle;
|
FTimerHandle StaminaTimerHandle;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IsHeavyAttack;
|
bool IsHeavyAttack;
|
||||||
float AttackHeldTime;
|
float AttackHeldTime;
|
||||||
bool bAttackCharged;
|
bool bAttackCharged;
|
||||||
bool bCanMove = true;
|
bool bCanMove = true;
|
||||||
bool bHitFront;
|
bool bHitFront;
|
||||||
FHitResult LastHitInfo;
|
FHitResult LastHitInfo;
|
||||||
|
FGameplayTagContainer OwnedGameplayTags;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,16 @@ FCombatGameplayTags FCombatGameplayTags::GameplayTags;
|
||||||
|
|
||||||
void FCombatGameplayTags::InitializeNativeGameplayTags()
|
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;
|
return;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player
|
||||||
|
*/
|
||||||
|
GameplayTags.Character_Player = UGameplayTagsManager::Get().AddNativeGameplayTag(
|
||||||
|
FName("Character.Player"),
|
||||||
|
FString("Player")
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State
|
* State
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ public:
|
||||||
static void InitializeNativeGameplayTags();
|
static void InitializeNativeGameplayTags();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
//Character
|
||||||
|
FGameplayTag Character_Player;
|
||||||
|
|
||||||
//State
|
//State
|
||||||
FGameplayTag Character_State_Attacking;
|
FGameplayTag Character_State_Attacking;
|
||||||
FGameplayTag Character_State_Dead;
|
FGameplayTag Character_State_Dead;
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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;
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue