[박치영]

- 각종 버그 조치
- 몬스터 공격 시 회전기능 추가
- 구르기 시 무적기능 추가
main
PCYPC\pcy35 2023-09-05 17:13:47 +09:00
parent 86dbaf0037
commit 8da4bccfe5
21 changed files with 149 additions and 48 deletions

View File

@ -145,4 +145,5 @@ ManualIPAddress=
+ClassRedirects=(OldName="/Script/D1.CombatCharacter",NewName="/Script/D1.CombatPlayerCharacter")
+FunctionRedirects=(OldName="/Script/D1.ICombatInterface.PerformCombatAction",NewName="/Script/D1.ICombatInterface.PerformAction")
+FunctionRedirects=(OldName="/Script/D1.ICombatInterface.PerformCombatAttack",NewName="/Script/D1.ICombatInterface.PerformAttack")
+FunctionRedirects=(OldName="/Script/D1.ICombatInterface.SetIFrames",NewName="/Script/D1.ICombatInterface.SetIFrame")

View File

@ -4,8 +4,14 @@
#include "AI/BehaviorTreeNodes/T_PerformAction.h"
#include "AIController.h"
#include "Definitions/CombatGameplayTags.h"
#include "Interface/CombatInterface.h"
UT_PerformAction::UT_PerformAction()
{
StateTag = FCombatGameplayTags::Get().Character_State_GeneralActionState;
}
EBTNodeResult::Type UT_PerformAction::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
EBTNodeResult::Type result = Super::ExecuteTask(OwnerComp, NodeMemory);

View File

@ -15,6 +15,7 @@ class D1_API UT_PerformAction : public UBTTaskNode
GENERATED_BODY()
public:
UT_PerformAction();
virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
private:

View File

@ -48,5 +48,5 @@ private:
UPROPERTY(EditAnywhere, Blueprintable, Category="Initialization", meta=(AllowPrivateAccess="true"))
FName WeaponHandSocketName;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true"))
TObjectPtr<class UUserWidget> BossHealthWidget;
TObjectPtr<UUserWidget> BossHealthWidget;
};

View File

@ -53,41 +53,32 @@ void ACombatAIController::OnPossess(APawn* InPawn)
void ACombatAIController::OnUpdatePerception(const TArray<AActor*>& PerceivedActors)
{
for (auto SensoredActor : PerceivedActors)
for (auto SensoredActor : PerceivedActors) //탐지된 Actor
{
IGameplayTagAssetInterface* CurActor = Cast<IGameplayTagAssetInterface>(SensoredActor); //Player가 아닌 Actor는 탐지되도 반응 없게 함
if(!CurActor)
continue;
if(!CurActor->HasMatchingGameplayTag(FCombatGameplayTags::Get().Character_Player))
continue;
FActorPerceptionBlueprintInfo PerceptionInfo;
GetPerceptionComponent()->GetActorsPerception(SensoredActor, PerceptionInfo);
for(int i = 0; i < PerceptionInfo.LastSensedStimuli.Num(); i++)
for(int i = 0; i < PerceptionInfo.LastSensedStimuli.Num(); i++) //탐지방식에 따른 for문
{
auto Info = PerceptionInfo.LastSensedStimuli[i];
auto SensedClass = UAIPerceptionSystem::GetSenseClassForStimulus(this, Info);
if(SensedClass == UAISense_Sight::StaticClass())
{
if(Info.WasSuccessfullySensed())
{
IGameplayTagAssetInterface* CurActor = Cast<IGameplayTagAssetInterface>(SensoredActor);
if(!CurActor)
continue;
if(CurActor->HasMatchingGameplayTag(FCombatGameplayTags::Get().Character_Player))
SetTargetActor(SensoredActor);
}
else
SetTargetActor(SensoredActor);
}
else if(SensedClass == UAISense_Damage::StaticClass())
{
if(Info.WasSuccessfullySensed() && !Info.IsExpired()) //After DamageConfig->GetMaxAge then Expired
{
IGameplayTagAssetInterface* CurActor = Cast<IGameplayTagAssetInterface>(SensoredActor);
if(!CurActor)
continue;
if(CurActor->HasMatchingGameplayTag(FCombatGameplayTags::Get().Character_Player))
SetTargetActor(SensoredActor);
}
}
}
}
}
void ACombatAIController::OnCombatToggle(bool IsCombatEnabled)

View File

@ -13,6 +13,7 @@
#include "Engine/DamageEvents.h"
#include "NiagaraFunctionLibrary.h"
#include "Components/CollisionComponent.h"
#include "Components/TimelineComponent.h"
#include "Components/WidgetComponent.h"
#include "DamageType/AttackDamageType.h"
#include "Kismet/KismetMathLibrary.h"
@ -89,6 +90,11 @@ AMasterAI::AMasterAI()
InputCollisionObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Pawn));
MainWeaponCollisionComponent->SetCollisionObjectTypes(InputCollisionObjectTypes);
MainWeaponCollisionComponent->SetDrawDebugType(EDrawDebugTrace::None);
FGameplayTagContainer GameplayTags(FCombatGameplayTags::Get().Character_Enemy);
MainWeaponCollisionComponent->SetGameplayTagsIgnore(GameplayTags);
//Settings OwnedGameplayTags
OwnedGameplayTags.AddTag(FCombatGameplayTags::Get().Character_Enemy);
//Setting MovementSpeed
MovementSpeedMode = EMovementSpeedMode::Jogging;
@ -96,20 +102,27 @@ AMasterAI::AMasterAI()
JoggingSpeed = 500.f;
SprintSpeed = 700.f;
//Settings OwnedGameplayTags
OwnedGameplayTags.AddTag(FCombatGameplayTags::Get().Character_Enemy);
PelvisBoneName = TEXT("pelvis");
//Setting Timeline
RotateToTargetTimeLineComponent = CreateDefaultSubobject<UTimelineComponent>(TEXT("RotateToTargetTimeLineComponent"));
}
void AMasterAI::BeginPlay()
{
Super::BeginPlay();
// BP의 BeginPlay가 먼저 호출됨 (ReceiveBeginPlay)
// 따라서 생성자로 올림
//StatsComponent->InitializeStats();
//Setting Timeline
FOnTimelineFloat TimelineFloatCallback;
TimelineFloatCallback.BindUFunction(this, FName("RotateToTargetUpdate"));
RotateToTargetTimeLineComponent->SetTimelineLength(0.25f);
RotateToTargetTimeLineComponent->SetLooping(false);
if(CurveFloatTimeline)
RotateToTargetTimeLineComponent->AddInterpFloat(CurveFloatTimeline, TimelineFloatCallback);
}
float AMasterAI::TakeDamage(float Damage, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
@ -178,8 +191,8 @@ FRotator AMasterAI::GetDesiredRotation_Implementation()
bool AMasterAI::CanReceiveDamage_Implementation()
{
bool result;
result = (StateManagerComponent->GetCurrentState() != FCombatGameplayTags::Get().Character_State_Dead);
bool result = (StateManagerComponent->GetCurrentState() != FCombatGameplayTags::Get().Character_State_Dead);
result &= !bEnableIFrame;
return result;
}
@ -198,6 +211,11 @@ void AMasterAI::DeactivateCollision_Implementation(ECollisionPart CollisionPart)
MainWeaponCollisionComponent->DeactivateCollision();
}
void AMasterAI::SetIFrame_Implementation(bool InputEnableIFrame)
{
bEnableIFrame = InputEnableIFrame;
}
float AMasterAI::PerformAction(FGameplayTag ActionTag, FGameplayTag StateTag, int32 MontageIndex, bool bRandomIndex)
{
TArray<UAnimMontage*> montages = GetActionMontage(ActionTag);
@ -280,6 +298,7 @@ void AMasterAI::OnTargeted(bool bIsTargeted)
void AMasterAI::OnTargetSet(AActor* NewTarget)
{
TargetActor = NewTarget;
}
void AMasterAI::SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode)
@ -310,7 +329,9 @@ void AMasterAI::CharacterStateBegin(FGameplayTag CharState)
if (FGameplayTag::EmptyTag == CharState)
{/*None*/}
else if (FCombatGameplayTags::Get().Character_State_Attacking == CharState)
{/*None*/}
{
RotateToTarget();
}
else if (FCombatGameplayTags::Get().Character_State_Dodging == CharState)
{/*None*/}
else if (FCombatGameplayTags::Get().Character_State_GeneralActionState == CharState)
@ -328,7 +349,9 @@ void AMasterAI::CharacterStateEnd(FGameplayTag CharState)
if (FGameplayTag::EmptyTag == CharState)
{/*None*/}
else if (FCombatGameplayTags::Get().Character_State_Attacking == CharState)
{/*None*/}
{
StopRotateToTarget();
}
else if (FCombatGameplayTags::Get().Character_State_Dodging == CharState)
{/*None*/}
else if (FCombatGameplayTags::Get().Character_State_GeneralActionState == CharState)
@ -428,6 +451,37 @@ void AMasterAI::ApplyImpactEffect(EDamageType InDamageType)
UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), HitEmitter, LastHitInfo.Location);
}
void AMasterAI::RotateToTarget()
{
RotateToTargetTimeLineComponent->PlayFromStart();
}
void AMasterAI::StopRotateToTarget()
{
RotateToTargetTimeLineComponent->Stop();
}
void AMasterAI::RotateToTargetUpdate(float Value)
{
if(!IsValid(TargetActor))
return;
const FRotator CurrentRotator = GetActorRotation();
FVector StartVector = GetActorLocation();
FVector TargetVector = TargetActor->GetActorLocation();
FRotator TargetRotator = UKismetMathLibrary::FindLookAtRotation(StartVector, TargetVector);
UWorld* WorldPointer = GetWorld();
if(!WorldPointer)
return;
double deltaTime = UGameplayStatics::GetWorldDeltaSeconds(WorldPointer);
FRotator NewRotator = FMath::Lerp<FRotator, float>(CurrentRotator, TargetRotator, Value);
NewRotator.Roll = CurrentRotator.Roll;
NewRotator.Pitch = CurrentRotator.Pitch;
SetActorRotation(NewRotator);
}
void AMasterAI::PerformDeath()
{
EnableRagdoll();

View File

@ -64,6 +64,9 @@ public:
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void DeactivateCollision(ECollisionPart CollisionPart);
virtual void DeactivateCollision_Implementation(ECollisionPart CollisionPart) override;
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void SetIFrame(bool InputEnableIFrame);
virtual void SetIFrame_Implementation(bool InputEnableIFrame) override;
virtual EMovementSpeedMode GetCombatMovementSpeedMode() override { return GetMovementSpeedMode(); }
virtual float PerformAction(FGameplayTag ActionTag, FGameplayTag StateTag, int32 MontageIndex, bool bRandomIndex);
@ -75,7 +78,7 @@ public:
// Inherited via IGameplayTagAssetInterface
virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override { TagContainer = OwnedGameplayTags; }
public: //Using Child Class
public:
virtual void OnTargetSet(AActor* NewTarget);
public:
void SetMovementSpeedMode(EMovementSpeedMode NewSpeedMode);
@ -95,6 +98,12 @@ private:
void ApplyHitReaction(EDamageType InDamageType);
void ApplyImpactEffect(EDamageType InDamageType);
//Timeline
void RotateToTarget();
void StopRotateToTarget();
UFUNCTION()
void RotateToTargetUpdate(float Value);
protected:
virtual void PerformDeath();
bool PerformHitStun();
@ -159,11 +168,21 @@ private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GameplayTags", meta = (AllowPrivateAccess = "true"))
FGameplayTagContainer OwnedGameplayTags;
private: //Timeline
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Timeline", meta = (AllowPrivateAccess = "true"))
TObjectPtr<class UTimelineComponent> RotateToTargetTimeLineComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timeline", meta = (AllowPrivateAccess = "true"))
TObjectPtr<UCurveFloat> CurveFloatTimeline;
const float RotateToTargetInterpSpeed = 9.f;
private:
FTimerHandle StaminaTimerHandle;
private:
bool bCanMove = true;
bool bHitFront;
bool bEnableIFrame;
FHitResult LastHitInfo;
UPROPERTY()
TObjectPtr<AActor> TargetActor;
};

View File

@ -103,11 +103,7 @@ ACombatPlayerCharacter::ACombatPlayerCharacter()
PelvisBoneName = TEXT("pelvis");
//Setting Timeline
FOnTimelineFloat CurveFloatCallback;
CurveFloatCallback.BindUFunction(this, FName("RotateToTargetUpdate"));
RotateToTargetTimeLineComponent = CreateDefaultSubobject<UTimelineComponent>(TEXT("RotateToTargetTimeLineComponent"));
RotateToTargetTimeLineComponent->SetTimelineLength(5.0f);
RotateToTargetTimeLineComponent->AddInterpFloat(CurveFloatTimeline, CurveFloatCallback);
}
void ACombatPlayerCharacter::BeginPlay()
@ -131,6 +127,14 @@ void ACombatPlayerCharacter::BeginPlay()
ABaseEquippable* SpawnItem = Cast<ABaseEquippable>(GetWorld()->SpawnActor(Weapon, &GetActorTransform(), spawnParam));
if (SpawnItem)
SpawnItem->OnEquipped();
//Setting Timeline - if you set on Constructor, Can not get Curve
FOnTimelineFloat TimelineFloatCallback;
TimelineFloatCallback.BindUFunction(this, FName("RotateToTargetUpdate"));
RotateToTargetTimeLineComponent->SetTimelineLength(5.0f);
RotateToTargetTimeLineComponent->SetLooping(false);
if(CurveFloatTimeline)
RotateToTargetTimeLineComponent->AddInterpFloat(CurveFloatTimeline, TimelineFloatCallback);
}
void ACombatPlayerCharacter::Tick(float DeltaSeconds)
@ -200,8 +204,8 @@ FRotator ACombatPlayerCharacter::GetDesiredRotation_Implementation()
bool ACombatPlayerCharacter::CanReceiveDamage_Implementation()
{
bool result;
result = (StateManagerComponent->GetCurrentState() != FCombatGameplayTags::Get().Character_State_Dead);
bool result = (StateManagerComponent->GetCurrentState() != FCombatGameplayTags::Get().Character_State_Dead);
result &= !bEnableIFrame;
return result;
}
@ -270,6 +274,11 @@ void ACombatPlayerCharacter::DeactivateCollision_Implementation(ECollisionPart C
weapon->DeactivateCollision(CollisionPart);
}
void ACombatPlayerCharacter::SetIFrame_Implementation(bool InputEnableIFrame)
{
bEnableIFrame = InputEnableIFrame;
}
float ACombatPlayerCharacter::PerformAction(FGameplayTag ActionTag, FGameplayTag StateTag, int32 MontageIndex, bool bRandomIndex)
{
ABaseWeapon* CurrentWeapon = CombatComponent->GetMainWeapon();
@ -721,14 +730,21 @@ void ACombatPlayerCharacter::StopRotateToTarget()
RotateToTargetTimeLineComponent->Stop();
}
void ACombatPlayerCharacter::RotateToTargetUpdate(float Output)
void ACombatPlayerCharacter::RotateToTargetUpdate(float Value)
{
if(!IsValid(TargetingComponent))
if(!IsValid(TargetingComponent->GetTargetActor()))
return;
const FRotator CurrentRotator = GetActorRotation();
FRotator TargetRotator = UKismetMathLibrary::FindLookAtRotation(GetActorLocation(), TargetingComponent->GetTargetActor()->GetActorLocation());
double deltaTime = UGameplayStatics::GetWorldDeltaSeconds(GetOwner());
FVector StartVector = GetActorLocation();
FVector TargetVector = TargetingComponent->GetTargetActor()->GetActorLocation();
FRotator TargetRotator = UKismetMathLibrary::FindLookAtRotation(StartVector, TargetVector);
UWorld* WorldPointer = GetWorld();
if(!WorldPointer)
return;
double deltaTime = UGameplayStatics::GetWorldDeltaSeconds(WorldPointer);
FRotator NewRotator = FMath::RInterpTo(CurrentRotator, TargetRotator, deltaTime, RotateToTargetInterpSpeed);
NewRotator.Roll = CurrentRotator.Roll;
NewRotator.Pitch = CurrentRotator.Pitch;

View File

@ -115,6 +115,9 @@ public:
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void DeactivateCollision(ECollisionPart CollisionPart);
virtual void DeactivateCollision_Implementation(ECollisionPart CollisionPart) override;
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void SetIFrame(bool InputEnableIFrame);
virtual void SetIFrame_Implementation(bool InputEnableIFrame) override;
virtual EMovementSpeedMode GetCombatMovementSpeedMode() override { return GetMovementSpeedMode(); }
virtual float PerformAction(FGameplayTag ActionTag, FGameplayTag StateTag, int32 MontageIndex, bool bRandomIndex = false);
@ -163,7 +166,8 @@ private:
//Timeline
void RotateToTarget();
void StopRotateToTarget();
void RotateToTargetUpdate(float Output);
UFUNCTION()
void RotateToTargetUpdate(float Value);
private:
void PerformDeath();
@ -233,6 +237,7 @@ private:
bool bAttackCharged;
bool bCanMove = true;
bool bHitFront;
bool bEnableIFrame;
FHitResult LastHitInfo;
FGameplayTagContainer OwnedGameplayTags;
};

View File

@ -65,14 +65,17 @@ void UCollisionComponent::ActivateCollision()
bool UCollisionComponent::CanHitActor(AActor* InActor)
{
bool result = false;
bool result = true;
IGameplayTagAssetInterface* tagInterface = Cast<IGameplayTagAssetInterface>(InActor);
if(tagInterface)
if(!tagInterface)
return false;
else
{
result &= !tagInterface->HasAnyMatchingGameplayTags(GameplayTagsIgnore); //Ignore Tag
result &= !AlreadyHitActors.Contains(InActor); //Alread Hit
result &= !ActorsToIgnore.Contains(InActor); //Ignore actor
}
return result;
}
}

View File

@ -160,7 +160,10 @@ void UTargetingComponent::UpdateTargetingControlRotation()
TargetLocation = TargetActor->GetActorLocation() - FVector(0.f, 0.f, 100.f);
FRotator TargetRotation = UKismetMathLibrary::FindLookAtRotation(GetOwner()->GetActorLocation(), TargetLocation);
FRotator CameraRotation = FMath::RInterpTo(OwnerController->K2_GetActorRotation(), TargetRotation, UGameplayStatics::GetWorldDeltaSeconds(GetOwner()), TargetRotationInterpSpeed);
UWorld* WorldPointer = GetWorld();
if(!WorldPointer)
return;
FRotator CameraRotation = FMath::RInterpTo(OwnerController->K2_GetActorRotation(), TargetRotation, UGameplayStatics::GetWorldDeltaSeconds(WorldPointer), TargetRotationInterpSpeed);
OwnerController->SetControlRotation(UKismetMathLibrary::MakeRotator(OwnerController->K2_GetActorRotation().Roll, CameraRotation.Pitch, CameraRotation.Yaw));
}
else

View File

@ -4,6 +4,7 @@
#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
#include "Definitions/CombatGameplayTags.h"
#include "Definitions/GameEnums.h"
#include "UObject/Interface.h"
#include "CombatInterface.generated.h"
@ -40,12 +41,13 @@ public:
void ActivateCollision(ECollisionPart CollisionPart);
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void DeactivateCollision(ECollisionPart CollisionPart);
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void SetIFrame(bool InputEnableIFrame);
UFUNCTION()
virtual EMovementSpeedMode GetCombatMovementSpeedMode() = 0;
UFUNCTION(Category="CombatActions")
virtual float PerformAction(FGameplayTag ActionTag, FGameplayTag StateTag, int32 MontageIndex, bool bRandomIndex = false);
virtual float PerformAction(FGameplayTag ActionTag, FGameplayTag StateTag = FCombatGameplayTags::Get().Character_State_GeneralActionState, int32 MontageIndex = 0, bool bRandomIndex = false);
UFUNCTION(Category="CombatActions")
virtual float PerformAttack(FGameplayTag AttackType, int32 AttackIndex, bool bRandomIndex = false);