[박치영] Shield 작업 완료
parent
e153ca9ccc
commit
6f59d664d6
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -34,3 +34,29 @@ void ABaseShield::OnUnequipped()
|
||||||
Super::OnUnequipped();
|
Super::OnUnequipped();
|
||||||
CombatComponent->SetShieldWeapon(nullptr);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -17,4 +17,9 @@ class D1_API ABaseShield : public ABaseWeapon
|
||||||
public:
|
public:
|
||||||
virtual void OnEquipped() override;
|
virtual void OnEquipped() override;
|
||||||
virtual void OnUnequipped() override;
|
virtual void OnUnequipped() override;
|
||||||
|
virtual TArray<UAnimMontage*> GetActionMontage(FGameplayTag characterAction) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Montages")
|
||||||
|
TArray<TObjectPtr<UAnimMontage>> BlockAnimations;
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
virtual void ToggleWeaponCombat(bool EnableCombat);
|
virtual void ToggleWeaponCombat(bool EnableCombat);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TArray<UAnimMontage*> GetActionMontage(FGameplayTag characterAction);
|
virtual TArray<UAnimMontage*> GetActionMontage(FGameplayTag characterAction);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization")
|
||||||
|
|
|
@ -188,6 +188,8 @@ void ACombatPlayerCharacter::ResetCombat_Implementation()
|
||||||
CombatComponent->ResetAttack();
|
CombatComponent->ResetAttack();
|
||||||
StateManagerComponent->ResetState();
|
StateManagerComponent->ResetState();
|
||||||
StateManagerComponent->SetCurrentAction(FGameplayTag::EmptyTag);
|
StateManagerComponent->SetCurrentAction(FGameplayTag::EmptyTag);
|
||||||
|
if(CanPerformBlock())
|
||||||
|
CombatComponent->SetBlockingState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FRotator ACombatPlayerCharacter::GetDesiredRotation_Implementation()
|
FRotator ACombatPlayerCharacter::GetDesiredRotation_Implementation()
|
||||||
|
@ -542,6 +544,7 @@ void ACombatPlayerCharacter::ToggleLockOn(const FInputActionValue& Value)
|
||||||
|
|
||||||
void ACombatPlayerCharacter::Blocking(const FInputActionValue& Value)
|
void ACombatPlayerCharacter::Blocking(const FInputActionValue& Value)
|
||||||
{
|
{
|
||||||
|
bIsBlockPressed = true;
|
||||||
if(CanPerformBlock())
|
if(CanPerformBlock())
|
||||||
{
|
{
|
||||||
CombatComponent->SetBlockingState(true);
|
CombatComponent->SetBlockingState(true);
|
||||||
|
@ -550,6 +553,7 @@ void ACombatPlayerCharacter::Blocking(const FInputActionValue& Value)
|
||||||
|
|
||||||
void ACombatPlayerCharacter::StopBlocking(const FInputActionValue& Value)
|
void ACombatPlayerCharacter::StopBlocking(const FInputActionValue& Value)
|
||||||
{
|
{
|
||||||
|
bIsBlockPressed = false;
|
||||||
CombatComponent->SetBlockingState(false);
|
CombatComponent->SetBlockingState(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,19 +715,26 @@ void ACombatPlayerCharacter::SprintStaminaCost()
|
||||||
|
|
||||||
void ACombatPlayerCharacter::ApplyHitReaction(EDamageType InDamageType)
|
void ACombatPlayerCharacter::ApplyHitReaction(EDamageType InDamageType)
|
||||||
{
|
{
|
||||||
switch (InDamageType)
|
if(WasHitBlocked())
|
||||||
{
|
{
|
||||||
case EDamageType::None:
|
PerformBlock();
|
||||||
PerformHitStun();
|
}
|
||||||
break;
|
else
|
||||||
case EDamageType::MeleeDamage:
|
{
|
||||||
PerformHitStun();
|
switch (InDamageType)
|
||||||
break;
|
{
|
||||||
case EDamageType::KnockdownDamage:
|
case EDamageType::None:
|
||||||
PerformKnockdown();
|
PerformHitStun();
|
||||||
break;
|
break;
|
||||||
default:
|
case EDamageType::MeleeDamage:
|
||||||
break;
|
PerformHitStun();
|
||||||
|
break;
|
||||||
|
case EDamageType::KnockdownDamage:
|
||||||
|
PerformKnockdown();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -738,15 +749,18 @@ void ACombatPlayerCharacter::ApplyImpactEffect(EDamageType InDamageType)
|
||||||
|
|
||||||
void ACombatPlayerCharacter::ReceiveDamage(float Damage, const FPointDamageEvent* pointDamageEvent, const UAttackDamageType* damageTypeClass, AController* eventInstigator)
|
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);
|
bHitFront = UKismetMathLibrary::InRange_FloatFloat(this->GetDotProductTo(eventInstigator->GetPawn()), -0.1f, 1.f);
|
||||||
LastHitInfo = pointDamageEvent->HitInfo;
|
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())
|
if (CanReceiveHitReaction())
|
||||||
ApplyHitReaction(damageTypeClass->DamageType);
|
ApplyHitReaction(damageTypeClass->DamageType);
|
||||||
|
@ -754,15 +768,18 @@ void ACombatPlayerCharacter::ReceiveDamage(float Damage, const FPointDamageEvent
|
||||||
|
|
||||||
void ACombatPlayerCharacter::ReceiveDamage(float Damage, const FRadialDamageEvent* radialDamageEvent, const UAttackDamageType* damageTypeClass, AController* eventInstigator)
|
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);
|
bHitFront = UKismetMathLibrary::InRange_FloatFloat(this->GetDotProductTo(eventInstigator->GetPawn()), -0.1f, 1.f);
|
||||||
LastHitInfo = radialDamageEvent->ComponentHits[0];
|
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())
|
if (CanReceiveHitReaction())
|
||||||
ApplyHitReaction(damageTypeClass->DamageType);
|
ApplyHitReaction(damageTypeClass->DamageType);
|
||||||
|
@ -858,6 +875,23 @@ bool ACombatPlayerCharacter::PerformKnockdown()
|
||||||
return true;
|
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 ACombatPlayerCharacter::CanPerformToggleCombat()
|
||||||
{
|
{
|
||||||
bool ReturnValue = true;
|
bool ReturnValue = true;
|
||||||
|
@ -952,6 +986,7 @@ bool ACombatPlayerCharacter::CanPerformBlock()
|
||||||
ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputContainer);
|
ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputContainer);
|
||||||
ReturnValue &= CombatComponent->GetCombatEnabled();
|
ReturnValue &= CombatComponent->GetCombatEnabled();
|
||||||
ReturnValue &= IsValid(CombatComponent->GetShieldWeapon());
|
ReturnValue &= IsValid(CombatComponent->GetShieldWeapon());
|
||||||
|
ReturnValue &= bIsBlockPressed; //Block Key를 눌렀는가?
|
||||||
|
|
||||||
return ReturnValue;
|
return ReturnValue;
|
||||||
}
|
}
|
||||||
|
@ -970,4 +1005,12 @@ FGameplayTag ACombatPlayerCharacter::GetDesiredAttackType()
|
||||||
return FCombatGameplayTags::Get().Character_Action_Attack_LightAttack;
|
return FCombatGameplayTags::Get().Character_Action_Attack_LightAttack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ACombatPlayerCharacter::WasHitBlocked()
|
||||||
|
{
|
||||||
|
if(IsValid(CombatComponent))
|
||||||
|
return (CombatComponent->GetIsBlocking() && bHitFront);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,7 @@ private:
|
||||||
void PerformDeath();
|
void PerformDeath();
|
||||||
bool PerformHitStun();
|
bool PerformHitStun();
|
||||||
bool PerformKnockdown();
|
bool PerformKnockdown();
|
||||||
|
bool PerformBlock();
|
||||||
|
|
||||||
protected: //Check Func
|
protected: //Check Func
|
||||||
bool CanPerformToggleCombat();
|
bool CanPerformToggleCombat();
|
||||||
|
@ -194,6 +195,7 @@ protected: //Check Func
|
||||||
bool CanPerformSprint();
|
bool CanPerformSprint();
|
||||||
bool CanPerformBlock();
|
bool CanPerformBlock();
|
||||||
FGameplayTag GetDesiredAttackType();
|
FGameplayTag GetDesiredAttackType();
|
||||||
|
bool WasHitBlocked();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
|
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
|
||||||
|
@ -236,6 +238,7 @@ public:
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Montage|Death", meta = (AllowPrivateAccess = "true"))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Montage|Death", meta = (AllowPrivateAccess = "true"))
|
||||||
TArray<TObjectPtr<UAnimMontage>> DeathAnimations;
|
TArray<TObjectPtr<UAnimMontage>> DeathAnimations;
|
||||||
|
|
||||||
|
|
||||||
private: //Timeline
|
private: //Timeline
|
||||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Timeline", meta = (AllowPrivateAccess = "true"))
|
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Timeline", meta = (AllowPrivateAccess = "true"))
|
||||||
TObjectPtr<UTimelineComponent> RotateToTargetTimeLineComponent;
|
TObjectPtr<UTimelineComponent> RotateToTargetTimeLineComponent;
|
||||||
|
@ -253,6 +256,7 @@ private:
|
||||||
bool bCanMove = true;
|
bool bCanMove = true;
|
||||||
bool bHitFront;
|
bool bHitFront;
|
||||||
bool bEnableIFrame;
|
bool bEnableIFrame;
|
||||||
|
bool bIsBlockPressed;
|
||||||
FHitResult LastHitInfo;
|
FHitResult LastHitInfo;
|
||||||
FGameplayTagContainer OwnedGameplayTags;
|
FGameplayTagContainer OwnedGameplayTags;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
FORCEINLINE int32 GetAttackCount() { return AttackCount; }
|
FORCEINLINE int32 GetAttackCount() { return AttackCount; }
|
||||||
|
|
||||||
void SetBlockingState(bool enableBlocking);
|
void SetBlockingState(bool enableBlocking);
|
||||||
|
FORCEINLINE bool GetIsBlocking() {return bIsBlocking; }
|
||||||
FORCEINLINE void SetShieldWeapon(ABaseWeapon* inShield) { EquippedShield = inShield; }
|
FORCEINLINE void SetShieldWeapon(ABaseWeapon* inShield) { EquippedShield = inShield; }
|
||||||
FORCEINLINE ABaseWeapon* GetShieldWeapon() { return EquippedShield; }
|
FORCEINLINE ABaseWeapon* GetShieldWeapon() { return EquippedShield; }
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,11 @@ void FCombatGameplayTags::InitializeNativeGameplayTags()
|
||||||
FString("State Attacking")
|
FString("State Attacking")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
GameplayTags.Character_State_Blocking = UGameplayTagsManager::Get().AddNativeGameplayTag(
|
||||||
|
FName("Character.State.Blocking"),
|
||||||
|
FString("State Blocking")
|
||||||
|
);
|
||||||
|
|
||||||
GameplayTags.Character_State_Dead = UGameplayTagsManager::Get().AddNativeGameplayTag(
|
GameplayTags.Character_State_Dead = UGameplayTagsManager::Get().AddNativeGameplayTag(
|
||||||
FName("Character.State.Dead"),
|
FName("Character.State.Dead"),
|
||||||
FString("State Dead")
|
FString("State Dead")
|
||||||
|
@ -119,4 +124,9 @@ void FCombatGameplayTags::InitializeNativeGameplayTags()
|
||||||
FName("Character.Action.Attack.RareAttack"),
|
FName("Character.Action.Attack.RareAttack"),
|
||||||
FString("Action Attack RareAttack")
|
FString("Action Attack RareAttack")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
GameplayTags.Character_Action_Attack_Blocking = UGameplayTagsManager::Get().AddNativeGameplayTag(
|
||||||
|
FName("Character.Action.Attack.Blocking"),
|
||||||
|
FString("Action Attack Blocking")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ public:
|
||||||
|
|
||||||
//State
|
//State
|
||||||
FGameplayTag Character_State_Attacking;
|
FGameplayTag Character_State_Attacking;
|
||||||
|
FGameplayTag Character_State_Blocking;
|
||||||
FGameplayTag Character_State_Dead;
|
FGameplayTag Character_State_Dead;
|
||||||
FGameplayTag Character_State_Disable;
|
FGameplayTag Character_State_Disable;
|
||||||
FGameplayTag Character_State_Dodging;
|
FGameplayTag Character_State_Dodging;
|
||||||
|
@ -37,6 +38,7 @@ public:
|
||||||
FGameplayTag Character_Action_Attack_CloseRange;
|
FGameplayTag Character_Action_Attack_CloseRange;
|
||||||
FGameplayTag Character_Action_Attack_MediumRange;
|
FGameplayTag Character_Action_Attack_MediumRange;
|
||||||
FGameplayTag Character_Action_Attack_RareAttack;
|
FGameplayTag Character_Action_Attack_RareAttack;
|
||||||
|
FGameplayTag Character_Action_Attack_Blocking;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static FCombatGameplayTags GameplayTags;
|
static FCombatGameplayTags GameplayTags;
|
||||||
|
|
Loading…
Reference in New Issue