diff --git a/Source/D1/CombatCharacter.cpp b/Source/D1/CombatCharacter.cpp index 935f87e7..2bc2c848 100644 --- a/Source/D1/CombatCharacter.cpp +++ b/Source/D1/CombatCharacter.cpp @@ -57,15 +57,16 @@ ACombatCharacter::ACombatCharacter() // Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character) // are set in the derived blueprint asset named ThirdPersonCharacter (to avoid direct content references in C++) + + // Setting CombatComponent CombatComponent = CreateDefaultSubobject(TEXT("CombatComponent")); - CombatEnabled = false; - IsTogglingCombat = false; - IsDodge = false; - IsDisabled = false; - IsDead = false; - Health = 100.f; + // Setting StateManagerComponent + StateManagerComponent = CreateDefaultSubobject(TEXT("StateManagerComponent")); + StateManagerComponent->OnStateBegin.AddUObject(this, &ACombatCharacter::CharacterStateBegin); + StateManagerComponent->OnStateEnd.AddUObject(this, &ACombatCharacter::CharacterStateEnd); + Health = 100.f; PelvisBoneName = TEXT("pelvis"); } @@ -108,20 +109,24 @@ float ACombatCharacter::TakeDamage(float Damage, FDamageEvent const& DamageEvent //Hit Effect UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), HitEmitter, PointDamageEvent->HitInfo.Location); - //Play Animation - PlayAnimMontage(HitMontage); - - IsDisabled = true; + if (CanReceiveHitReaction()) + { + StateManagerComponent->SetState(ECharacterState::Disable); + + //Play Animation + PlayAnimMontage(HitMontage); + } } return fDamage; } void ACombatCharacter::ContinueAttack_Implementation() { - CombatComponent->SetIsAttacking(false); if (CombatComponent->GetIsAttackSaved()) { CombatComponent->SetIsAttackSaved(false); + if (StateManagerComponent->GetCurrentState() == ECharacterState::Attacking) + StateManagerComponent->SetState(ECharacterState::Nothing); AttackEvent(); } } @@ -134,8 +139,8 @@ void ACombatCharacter::ResetAttack_Implementation() void ACombatCharacter::ResetCombat_Implementation() { CombatComponent->ResetAttack(); - IsTogglingCombat = false; - IsDodge = false; + StateManagerComponent->ResetState(); + StateManagerComponent->SetState(ECharacterState::Nothing); } FRotator ACombatCharacter::GetDesiredRotation_Implementation() @@ -149,7 +154,9 @@ FRotator ACombatCharacter::GetDesiredRotation_Implementation() bool ACombatCharacter::CanReceiveDamage_Implementation() { - return !IsDead; + bool result; + result = (StateManagerComponent->GetCurrentState() != ECharacterState::Dead); + return result; } ////////////////////////////////////////////////////////////////////////// @@ -158,7 +165,8 @@ bool ACombatCharacter::CanReceiveDamage_Implementation() void ACombatCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) { // Set up action bindings - if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked(PlayerInputComponent)) { + if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked(PlayerInputComponent)) + { //Jumping EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump); @@ -247,7 +255,7 @@ void ACombatCharacter::ToggleCombat(const FInputActionValue& Value) void ACombatCharacter::LightAttack(const FInputActionValue& Value) { - if (CombatComponent->GetIsAttacking()) + if (StateManagerComponent->GetCurrentState() == ECharacterState::Attacking) CombatComponent->SetIsAttackSaved(true); else AttackEvent(); @@ -259,6 +267,49 @@ void ACombatCharacter::Dodge(const FInputActionValue& Value) PerformDodge(); } +void ACombatCharacter::CharacterStateBegin(ECharacterState CharState) +{ + switch (CharState) + { + case ECharacterState::Nothing: + break; + case ECharacterState::Attacking: + break; + case ECharacterState::Dodging: + break; + case ECharacterState::GeneralActionState: + break; + case ECharacterState::Dead: + PerformDeath(); + break; + case ECharacterState::Disable: + break; + default: + break; + } +} + +void ACombatCharacter::CharacterStateEnd(ECharacterState CharState) +{ + switch (CharState) + { + case ECharacterState::Nothing: + break; + case ECharacterState::Attacking: + break; + case ECharacterState::Dodging: + break; + case ECharacterState::GeneralActionState: + break; + case ECharacterState::Dead: + break; + case ECharacterState::Disable: + break; + default: + break; + } +} + void ACombatCharacter::ToggleCombatEvent() { ABaseWeapon* baseWeapon = CombatComponent->GetMainWeapon(); @@ -291,7 +342,7 @@ void ACombatCharacter::CharacterTakeDamage(float InDamage) Health = UKismetMathLibrary::Clamp(tmp, 0, Health); if (Health <= 0) - PerformDeath(); + StateManagerComponent->SetState(ECharacterState::Dead); } void ACombatCharacter::ApplyHitReactionPhysicsVelocity(float InitialSpeed) @@ -326,7 +377,7 @@ void ACombatCharacter::PerformAttack(int32 attackIndex) if(!IsValid(attackMontage)) return; - CombatComponent->SetIsAttacking(true); + StateManagerComponent->SetState(ECharacterState::Attacking); PlayAnimMontage(attackMontage); int idx = attackIndex + 1; @@ -352,7 +403,7 @@ void ACombatCharacter::PerformDodge() UAnimMontage* dodgeMontage = CurrentWeapon->GetDodgeMontage()[montageIndex]; if (IsValid(dodgeMontage)) { - IsDodge = true; + StateManagerComponent->SetState(ECharacterState::Dodging); PlayAnimMontage(dodgeMontage); } else @@ -364,7 +415,6 @@ void ACombatCharacter::PerformDodge() void ACombatCharacter::PerformDeath() { - IsDead = true; EnableRagdoll(); ApplyHitReactionPhysicsVelocity(2000.f); //Ãæµ¹À» Á» ´õ ±×·²½ÎÇÏ°Ô Çϱâ À§Çؼ­ µÞ¹æÇâÀ¸·Î Ãæ°Ý @@ -383,11 +433,15 @@ void ACombatCharacter::PerformDeath() bool ACombatCharacter::CanPerformToggleCombat() { bool ReturnValue = true; - ReturnValue &= !CombatComponent->GetIsAttacking(); - ReturnValue &= !IsTogglingCombat; - ReturnValue &= !IsDodge; - ReturnValue &= !IsDisabled; - ReturnValue &= !IsDead; + + TArray inputArr = { + ECharacterState::Attacking, + ECharacterState::Dodging, + ECharacterState::Dead, + ECharacterState::Disable, + ECharacterState::GeneralActionState + }; + ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputArr); ReturnValue &= !GetCharacterMovement()->IsFalling(); return ReturnValue; } @@ -395,23 +449,27 @@ bool ACombatCharacter::CanPerformToggleCombat() bool ACombatCharacter::CanPerformAttack() { bool ReturnValue = true; - ReturnValue &= !CombatComponent->GetIsAttacking(); - ReturnValue &= !IsTogglingCombat; - ReturnValue &= !IsDodge; - ReturnValue &= !IsDisabled; - ReturnValue &= !IsDead; - ReturnValue &= !GetCharacterMovement()->IsFalling(); + TArray inputArr = { + ECharacterState::Attacking, + ECharacterState::Dodging, + ECharacterState::Dead, + ECharacterState::Disable, + ECharacterState::GeneralActionState + }; + ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputArr); return ReturnValue; } bool ACombatCharacter::CanPerformDodge() { bool ReturnValue = true; - ReturnValue &= !CombatComponent->GetIsAttacking(); - ReturnValue &= !IsTogglingCombat; - ReturnValue &= !IsDodge; - ReturnValue &= !IsDisabled; - ReturnValue &= !IsDead; + TArray inputArr = { + ECharacterState::Dodging, + ECharacterState::Dead, + ECharacterState::Disable, + ECharacterState::GeneralActionState + }; + ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputArr); ReturnValue &= !GetCharacterMovement()->IsFalling(); return ReturnValue; } @@ -419,14 +477,26 @@ bool ACombatCharacter::CanPerformDodge() bool ACombatCharacter::CanJumping() { bool ReturnValue = true; - ReturnValue &= !CombatComponent->GetIsAttacking(); - ReturnValue &= !IsTogglingCombat; - ReturnValue &= !IsDodge; - ReturnValue &= !IsDisabled; - ReturnValue &= !IsDead; + TArray inputArr = { + ECharacterState::Dodging, + ECharacterState::Dead, + ECharacterState::Disable, + ECharacterState::GeneralActionState + }; + ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputArr); ReturnValue &= !GetCharacterMovement()->IsFalling(); return ReturnValue; } +bool ACombatCharacter::CanReceiveHitReaction() +{ + bool ReturnValue = true; + TArray inputArr = { + ECharacterState::Dead, + }; + ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputArr); + return ReturnValue; +} + diff --git a/Source/D1/CombatCharacter.h b/Source/D1/CombatCharacter.h index b3164ac9..e01f8ac4 100644 --- a/Source/D1/CombatCharacter.h +++ b/Source/D1/CombatCharacter.h @@ -6,6 +6,7 @@ #include "GameFramework/Character.h" #include "InputActionValue.h" #include "Interface/CombatInterface.h" +#include "Components/StateManagerComponent.h" #include "CombatCharacter.generated.h" @@ -93,6 +94,10 @@ protected: void LightAttack(const FInputActionValue& Value); void Dodge(const FInputActionValue& Value); +private: + void CharacterStateBegin(ECharacterState CharState); + void CharacterStateEnd(ECharacterState CharState); + private: void ToggleCombatEvent(); void AttackEvent(); @@ -102,6 +107,7 @@ private: void PerformAttack(int32 attackIndex); void PerformDodge(); + UFUNCTION(BlueprintCallable) //Àӽà void PerformDeath(); @@ -109,10 +115,14 @@ private: bool CanPerformAttack(); bool CanPerformDodge(); bool CanJumping(); + bool CanReceiveHitReaction(); public: UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true")) TObjectPtr CombatComponent; + UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true")) + TObjectPtr StateManagerComponent; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Weapon", meta = (AllowPrivateAccess = "true")) TSubclassOf Weapon; @@ -130,12 +140,5 @@ public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats", meta = (AllowPrivateAccess = "true")) float Health; -private: - bool CombatEnabled; - bool IsTogglingCombat; - bool IsDodge; - bool IsDisabled; - bool IsDead; - }; diff --git a/Source/D1/Components/CombatComponent.cpp b/Source/D1/Components/CombatComponent.cpp index d9670b94..ba62566a 100644 --- a/Source/D1/Components/CombatComponent.cpp +++ b/Source/D1/Components/CombatComponent.cpp @@ -34,7 +34,6 @@ void UCombatComponent::ResetAttack() { AttackCount = 0; bIsAttackSaved = false; - bIsAttacking = false; } void UCombatComponent::SetMainWeapon(ABaseWeapon* NewWeapon) diff --git a/Source/D1/Components/CombatComponent.h b/Source/D1/Components/CombatComponent.h index eb956a9f..8c764853 100644 --- a/Source/D1/Components/CombatComponent.h +++ b/Source/D1/Components/CombatComponent.h @@ -29,9 +29,6 @@ public: void SetMainWeapon(ABaseWeapon* NewWeapon); FORCEINLINE ABaseWeapon* GetMainWeapon() const; - FORCEINLINE void SetIsAttacking(bool attacking) { bIsAttacking = attacking; } - FORCEINLINE bool GetIsAttacking() const { return bIsAttacking; } - FORCEINLINE void SetIsAttackSaved(bool attackSaved) { bIsAttackSaved = attackSaved; } FORCEINLINE bool GetIsAttackSaved() const { return bIsAttackSaved; } @@ -48,9 +45,6 @@ private: UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true")) bool bIsAttackSaved; - UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true")) - bool bIsAttacking; - UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true")) int32 AttackCount; }; diff --git a/Source/D1/Components/StateManagerComponent.cpp b/Source/D1/Components/StateManagerComponent.cpp index 48819167..30517cec 100644 --- a/Source/D1/Components/StateManagerComponent.cpp +++ b/Source/D1/Components/StateManagerComponent.cpp @@ -36,9 +36,9 @@ void UStateManagerComponent::SetState(ECharacterState NewState) { if (NewState != CurrentState) { - //TODO : Delegate ÇÔ¼ö È£Ãâ (Call on State End) + OnStateEnd.Broadcast(CurrentState); CurrentState = NewState; - //TODO : Delegate ÇÔ¼ö È£Ãâ (Call on State Begin) + OnStateBegin.Broadcast(CurrentState); } } diff --git a/Source/D1/Components/StateManagerComponent.h b/Source/D1/Components/StateManagerComponent.h index 402a7282..fc84abd7 100644 --- a/Source/D1/Components/StateManagerComponent.h +++ b/Source/D1/Components/StateManagerComponent.h @@ -17,6 +17,9 @@ enum class ECharacterState : uint8 Disable UMETA(DisplayName = "Disable") }; +DECLARE_MULTICAST_DELEGATE_OneParam(FStateBegin, ECharacterState); +DECLARE_MULTICAST_DELEGATE_OneParam(FStateEnd, ECharacterState); + UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class D1_API UStateManagerComponent : public UActorComponent { @@ -39,6 +42,12 @@ public: ECharacterState GetCurrentState(); void ResetState(); bool IsCurrentStateEqualToAny(TArray StatesToCheck); + +public: //Delegate + FStateBegin OnStateBegin; + FStateEnd OnStateEnd; + private: ECharacterState CurrentState; + };