Compare commits

...

2 Commits

Author SHA1 Message Date
PCYPC\pcy35 6f59d664d6 [박치영] Shield 작업 완료 2023-11-15 21:10:23 +09:00
PCYPC\pcy35 e153ca9ccc [박치영] Shield 모션 작업 2023-11-15 15:37:42 +09:00
22 changed files with 137 additions and 43 deletions

View File

@ -46,7 +46,7 @@ ABossEnemy::ABossEnemy()
//Setting CombatComponent
//Setting others is Parents
CombatComponent->OnCombatToggled.BindUObject(this, &ABossEnemy::OnCombatToggled);
CombatComponent->OnCombatToggled.AddUObject(this, &ABossEnemy::OnCombatToggled);
}
void ABossEnemy::BeginPlay()

View File

@ -45,7 +45,7 @@ void ACombatAIController::OnPossess(APawn* InPawn)
MasterAI = AIpawn;
UCombatComponent* combatComponent = MasterAI->GetComponentByClass<UCombatComponent>();
combatComponent->OnCombatToggled.BindUObject(this, &ACombatAIController::OnCombatToggle);
combatComponent->OnCombatToggled.AddUObject(this, &ACombatAIController::OnCombatToggle);
RunBehaviorTree(MasterAI->GetBeHaviorTree());

View File

@ -44,7 +44,7 @@ AGruntlingEnemy::AGruntlingEnemy()
//Setting CombatComponent
//Setting others is Parents
CombatComponent->OnCombatToggled.BindUObject(this, &AGruntlingEnemy::OnCombatToggled);
CombatComponent->OnCombatToggled.AddUObject(this, &AGruntlingEnemy::OnCombatToggled);
}
void AGruntlingEnemy::BeginPlay()

View File

@ -44,7 +44,7 @@ AHeavyMobEnemy::AHeavyMobEnemy()
//Setting CombatComponent
//Setting others is Parents
CombatComponent->OnCombatToggled.BindUObject(this, &AHeavyMobEnemy::OnCombatToggled);
CombatComponent->OnCombatToggled.AddUObject(this, &AHeavyMobEnemy::OnCombatToggled);
}
void AHeavyMobEnemy::BeginPlay()

View File

@ -38,7 +38,7 @@ AMobEnemy::AMobEnemy()
//Setting CombatComponent
//Setting others is Parents
CombatComponent->OnCombatToggled.BindUObject(this, &AMobEnemy::OnCombatToggled);
CombatComponent->OnCombatToggled.AddUObject(this, &AMobEnemy::OnCombatToggled);
}
void AMobEnemy::BeginPlay()

View File

@ -14,7 +14,7 @@ void ABaseShield::OnEquipped()
if (!owner)
return;
CombatComponent = owner->GetComponentByClass<UCombatComponent>();
CombatComponent->OnCombatToggled.BindUObject(this, &ABaseWeapon::ToggleWeaponCombat);
CombatComponent->OnCombatToggled.AddUObject(this, &ABaseWeapon::ToggleWeaponCombat);
OwnerStateManager = owner->GetComponentByClass<UStateManagerComponent>();
@ -34,3 +34,29 @@ void ABaseShield::OnUnequipped()
Super::OnUnequipped();
CombatComponent->SetShieldWeapon(nullptr);
}
TArray<UAnimMontage*> ABaseShield::GetActionMontage(FGameplayTag characterAction)
{
TArray<UAnimMontage*> outputArr;
if (FCombatGameplayTags::Get().Character_Action_Attack_Blocking == characterAction)
outputArr = BlockAnimations;
else if (FCombatGameplayTags::Get().Character_Action_Attack_LightAttack == characterAction)
outputArr = LightAttackMontage;
else if (FCombatGameplayTags::Get().Character_Action_Attack_HeavyAttack == characterAction)
outputArr = HeavyAttackMontage;
else if (FCombatGameplayTags::Get().Character_Action_Attack_ChargedAttack == characterAction)
outputArr = ChargedAttackMontage;
else if (FCombatGameplayTags::Get().Character_Action_Attack_FallingAttack == characterAction)
outputArr = FallingAttackMontage;
else if (FCombatGameplayTags::Get().Character_Action_Attack_SprintAttack == characterAction)
outputArr = SprintAttackMontage;
else if (FCombatGameplayTags::Get().Character_Action_Dodge == characterAction)
outputArr = DodgeMontage;
else if (FCombatGameplayTags::Get().Character_Action_EnterCombat == characterAction)
outputArr.Add(EnterCombat);
else if (FCombatGameplayTags::Get().Character_Action_ExitCombat == characterAction)
outputArr.Add(ExitCombat);
return outputArr;
}

View File

@ -17,4 +17,9 @@ class D1_API ABaseShield : public ABaseWeapon
public:
virtual void OnEquipped() override;
virtual void OnUnequipped() override;
virtual TArray<UAnimMontage*> GetActionMontage(FGameplayTag characterAction) override;
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Montages")
TArray<TObjectPtr<UAnimMontage>> BlockAnimations;
};

View File

@ -51,11 +51,11 @@ void ABaseWeapon::OnEquipped()
if (!owner)
return;
CombatComponent = owner->GetComponentByClass<UCombatComponent>();
CombatComponent->OnCombatToggled.BindUObject(this, &ABaseWeapon::ToggleWeaponCombat);
CombatComponent->OnCombatToggled.AddUObject(this, &ABaseWeapon::ToggleWeaponCombat);
OwnerStateManager = owner->GetComponentByClass<UStateManagerComponent>();
if (CombatComponent->GetCombatEnabled()) //TODO : 방패 착용 후 Toggle Event 시 Weapon의 소켓이 안바뀌는 버그
if (CombatComponent->GetCombatEnabled())
AttachActor(HandSocketName);
else
AttachActor(AttachSocketName);

View File

@ -44,7 +44,7 @@ public:
virtual void ToggleWeaponCombat(bool EnableCombat);
public:
TArray<UAnimMontage*> GetActionMontage(FGameplayTag characterAction);
virtual TArray<UAnimMontage*> GetActionMontage(FGameplayTag characterAction);
protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")

View File

@ -21,8 +21,8 @@ void UCombatAnimInstance::NativeInitializeAnimation()
ensure(CombatComponent);
if(IsValid(CombatComponent))
{
CombatComponent->OnCombatToggled.BindUObject(this, &UCombatAnimInstance::UpdateCombatEnabled);
CombatComponent->OnBlockingSet.BindUObject(this, &UCombatAnimInstance::OnBlockingSet_Event);
CombatComponent->OnCombatToggled.AddUObject(this, &UCombatAnimInstance::UpdateCombatEnabled);
CombatComponent->OnBlockingSet.AddUObject(this, &UCombatAnimInstance::OnBlockingSet_Event);
}
}
}

View File

@ -69,7 +69,7 @@ ACombatPlayerCharacter::ACombatPlayerCharacter()
// Setting CombatComponent
CombatComponent = CreateDefaultSubobject<UCombatComponent>(TEXT("CombatComponent"));
CombatComponent->OnCombatToggled.BindUObject(this, &ACombatPlayerCharacter::CharacterCombatToggled);
CombatComponent->OnCombatToggled.AddUObject(this, &ACombatPlayerCharacter::CharacterCombatToggled);
// Setting StateManagerComponent
StateManagerComponent = CreateDefaultSubobject<UStateManagerComponent>(TEXT("StateManagerComponent"));
@ -188,6 +188,8 @@ void ACombatPlayerCharacter::ResetCombat_Implementation()
CombatComponent->ResetAttack();
StateManagerComponent->ResetState();
StateManagerComponent->SetCurrentAction(FGameplayTag::EmptyTag);
if(CanPerformBlock())
CombatComponent->SetBlockingState(true);
}
FRotator ACombatPlayerCharacter::GetDesiredRotation_Implementation()
@ -251,7 +253,8 @@ void ACombatPlayerCharacter::SetupPlayerInputComponent(class UInputComponent* Pl
EnhancedInputComponent->BindAction(ToggleLockOnAction, ETriggerEvent::Started, this, &ACombatPlayerCharacter::ToggleLockOn);
//Block
EnhancedInputComponent->BindAction(ToggleLockOnAction, ETriggerEvent::Started, this, &ACombatPlayerCharacter::ToggleLockOn);
EnhancedInputComponent->BindAction(BlockAction, ETriggerEvent::Triggered, this, &ACombatPlayerCharacter::Blocking);
EnhancedInputComponent->BindAction(BlockAction, ETriggerEvent::Completed, this, &ACombatPlayerCharacter::StopBlocking);
}
}
@ -541,14 +544,17 @@ void ACombatPlayerCharacter::ToggleLockOn(const FInputActionValue& Value)
void ACombatPlayerCharacter::Blocking(const FInputActionValue& Value)
{
bIsBlockPressed = true;
if(CanPerformBlock())
{
CombatComponent->SetBlockingState(true);
}
else
{
CombatComponent->SetBlockingState(false);
}
}
void ACombatPlayerCharacter::StopBlocking(const FInputActionValue& Value)
{
bIsBlockPressed = false;
CombatComponent->SetBlockingState(false);
}
void ACombatPlayerCharacter::CharacterStateBegin(FGameplayTag CharState)
@ -709,19 +715,26 @@ void ACombatPlayerCharacter::SprintStaminaCost()
void ACombatPlayerCharacter::ApplyHitReaction(EDamageType InDamageType)
{
switch (InDamageType)
if(WasHitBlocked())
{
case EDamageType::None:
PerformHitStun();
break;
case EDamageType::MeleeDamage:
PerformHitStun();
break;
case EDamageType::KnockdownDamage:
PerformKnockdown();
break;
default:
break;
PerformBlock();
}
else
{
switch (InDamageType)
{
case EDamageType::None:
PerformHitStun();
break;
case EDamageType::MeleeDamage:
PerformHitStun();
break;
case EDamageType::KnockdownDamage:
PerformKnockdown();
break;
default:
break;
}
}
}
@ -736,15 +749,18 @@ void ACombatPlayerCharacter::ApplyImpactEffect(EDamageType InDamageType)
void ACombatPlayerCharacter::ReceiveDamage(float Damage, const FPointDamageEvent* pointDamageEvent, const UAttackDamageType* damageTypeClass, AController* eventInstigator)
{
//스텟 관련 처리
StatsComponent->TakeDamageOnStat(Damage);
//앞에서 맞았는지 뒤에서 맞았는지 판별
bHitFront = UKismetMathLibrary::InRange_FloatFloat(this->GetDotProductTo(eventInstigator->GetPawn()), -0.1f, 1.f);
LastHitInfo = pointDamageEvent->HitInfo;
//play sound, effect
ApplyImpactEffect(damageTypeClass->DamageType);
//공격을 막았을 경우
if(WasHitBlocked())
Damage = 0.f; //막았을 때는 데미지 처리안함
else
ApplyImpactEffect(damageTypeClass->DamageType); //play sound, effect
//스텟 관련 처리
StatsComponent->TakeDamageOnStat(Damage);
if (CanReceiveHitReaction())
ApplyHitReaction(damageTypeClass->DamageType);
@ -752,15 +768,18 @@ void ACombatPlayerCharacter::ReceiveDamage(float Damage, const FPointDamageEvent
void ACombatPlayerCharacter::ReceiveDamage(float Damage, const FRadialDamageEvent* radialDamageEvent, const UAttackDamageType* damageTypeClass, AController* eventInstigator)
{
//스텟 관련 처리
StatsComponent->TakeDamageOnStat(Damage);
//앞에서 맞았는지 뒤에서 맞았는지 판별
bHitFront = UKismetMathLibrary::InRange_FloatFloat(this->GetDotProductTo(eventInstigator->GetPawn()), -0.1f, 1.f);
LastHitInfo = radialDamageEvent->ComponentHits[0];
//play sound, effect
ApplyImpactEffect(damageTypeClass->DamageType);
//공격을 막았을 경우
if(WasHitBlocked())
Damage = 0.f; //막았을 때는 데미지 처리안함
else
ApplyImpactEffect(damageTypeClass->DamageType); //play sound, effect
//스텟 관련 처리
StatsComponent->TakeDamageOnStat(Damage);
if (CanReceiveHitReaction())
ApplyHitReaction(damageTypeClass->DamageType);
@ -856,6 +875,23 @@ bool ACombatPlayerCharacter::PerformKnockdown()
return true;
}
bool ACombatPlayerCharacter::PerformBlock()
{
if(!IsValid(CombatComponent->GetShieldWeapon()))
return false;
TArray<UAnimMontage*> hitMontage = CombatComponent->GetShieldWeapon()->GetActionMontage(FCombatGameplayTags::Get().Character_Action_Attack_Blocking);
if(hitMontage.Num() <= 0)
return false;
int32 indexNum = FMath::RandRange(0, hitMontage.Num() - 1);
if(!hitMontage.IsValidIndex(indexNum))
return false;
StateManagerComponent->SetCurrentState(FCombatGameplayTags::Get().Character_State_Blocking);
PlayAnimMontage(hitMontage[indexNum]);
return true;
}
bool ACombatPlayerCharacter::CanPerformToggleCombat()
{
bool ReturnValue = true;
@ -950,6 +986,7 @@ bool ACombatPlayerCharacter::CanPerformBlock()
ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputContainer);
ReturnValue &= CombatComponent->GetCombatEnabled();
ReturnValue &= IsValid(CombatComponent->GetShieldWeapon());
ReturnValue &= bIsBlockPressed; //Block Key를 눌렀는가?
return ReturnValue;
}
@ -968,4 +1005,12 @@ FGameplayTag ACombatPlayerCharacter::GetDesiredAttackType()
return FCombatGameplayTags::Get().Character_Action_Attack_LightAttack;
}
bool ACombatPlayerCharacter::WasHitBlocked()
{
if(IsValid(CombatComponent))
return (CombatComponent->GetIsBlocking() && bHitFront);
else
return false;
}

View File

@ -151,6 +151,7 @@ protected:
void StopSprint(const FInputActionValue& Value);
void ToggleLockOn(const FInputActionValue& Value);
void Blocking(const FInputActionValue& Value);
void StopBlocking(const FInputActionValue& Value);
private://Delegate
void CharacterStateBegin(FGameplayTag CharState);
@ -183,6 +184,7 @@ private:
void PerformDeath();
bool PerformHitStun();
bool PerformKnockdown();
bool PerformBlock();
protected: //Check Func
bool CanPerformToggleCombat();
@ -193,6 +195,7 @@ protected: //Check Func
bool CanPerformSprint();
bool CanPerformBlock();
FGameplayTag GetDesiredAttackType();
bool WasHitBlocked();
public:
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
@ -234,6 +237,7 @@ public:
TObjectPtr<UAnimMontage> KnockdownBackMontage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Montage|Death", meta = (AllowPrivateAccess = "true"))
TArray<TObjectPtr<UAnimMontage>> DeathAnimations;
private: //Timeline
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Timeline", meta = (AllowPrivateAccess = "true"))
@ -252,6 +256,7 @@ private:
bool bCanMove = true;
bool bHitFront;
bool bEnableIFrame;
bool bIsBlockPressed;
FHitResult LastHitInfo;
FGameplayTagContainer OwnedGameplayTags;
};

View File

@ -19,7 +19,7 @@ void UCombatComponent::SetCombatEnabled(bool bInputCombat)
{
bCombatEnabled = bInputCombat;
OnCombatToggled.Execute(bInputCombat);
OnCombatToggled.Broadcast(bInputCombat);
// ACharacter* character = Cast<ACharacter>(GetOwner());
// if (character)
@ -57,7 +57,7 @@ void UCombatComponent::SetBlockingState(bool enableBlocking)
if(enableBlocking != bIsBlocking)
{
bIsBlocking = enableBlocking;
OnBlockingSet.Execute(bIsBlocking);
OnBlockingSet.Broadcast(bIsBlocking);
}
}

View File

@ -6,8 +6,8 @@
#include "Components/ActorComponent.h"
#include "CombatComponent.generated.h"
DECLARE_DELEGATE_OneParam(FOnCombatToggled, bool);
DECLARE_DELEGATE_OneParam(FOnBlockingSet, bool);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnCombatToggled, bool);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnBlockingSet, bool);
class ABaseWeapon;
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
@ -38,6 +38,7 @@ public:
FORCEINLINE int32 GetAttackCount() { return AttackCount; }
void SetBlockingState(bool enableBlocking);
FORCEINLINE bool GetIsBlocking() {return bIsBlocking; }
FORCEINLINE void SetShieldWeapon(ABaseWeapon* inShield) { EquippedShield = inShield; }
FORCEINLINE ABaseWeapon* GetShieldWeapon() { return EquippedShield; }

View File

@ -32,6 +32,11 @@ void FCombatGameplayTags::InitializeNativeGameplayTags()
FString("State Attacking")
);
GameplayTags.Character_State_Blocking = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Character.State.Blocking"),
FString("State Blocking")
);
GameplayTags.Character_State_Dead = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Character.State.Dead"),
FString("State Dead")
@ -119,4 +124,9 @@ void FCombatGameplayTags::InitializeNativeGameplayTags()
FName("Character.Action.Attack.RareAttack"),
FString("Action Attack RareAttack")
);
GameplayTags.Character_Action_Attack_Blocking = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Character.Action.Attack.Blocking"),
FString("Action Attack Blocking")
);
}

View File

@ -18,6 +18,7 @@ public:
//State
FGameplayTag Character_State_Attacking;
FGameplayTag Character_State_Blocking;
FGameplayTag Character_State_Dead;
FGameplayTag Character_State_Disable;
FGameplayTag Character_State_Dodging;
@ -37,6 +38,7 @@ public:
FGameplayTag Character_Action_Attack_CloseRange;
FGameplayTag Character_Action_Attack_MediumRange;
FGameplayTag Character_Action_Attack_RareAttack;
FGameplayTag Character_Action_Attack_Blocking;
private:
static FCombatGameplayTags GameplayTags;