[박치영] 장비 시스템 개편

main
pcyoung 2023-12-13 18:30:24 +09:00
parent 1b2cd5570c
commit 8c0f599634
22 changed files with 155 additions and 138 deletions

View File

@ -156,4 +156,5 @@ ManualIPAddress=
+PropertyRedirects=(OldName="/Script/D1.BaseConsumable.NumberOfUses",NewName="/Script/D1.BaseConsumable.CurrentNumberOfUses")
+PropertyRedirects=(OldName="/Script/D1.BaseConsumable.NumberOfUses",NewName="/Script/D1.BaseConsumable.CurrentNumberOfUses")
+PropertyRedirects=(OldName="/Script/D1.BaseConsumable.Value",NewName="/Script/D1.BaseConsumable.ModificationValue")
+PropertyRedirects=(OldName="/Script/D1.PickupActor.Item",NewName="/Script/D1.PickupActor.ItemClass")

Binary file not shown.

View File

@ -1,62 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Actor/BaseShield.h"
#include "Components/CollisionComponent.h"
#include "Components/CombatComponent.h"
#include "GameFramework/Character.h"
void ABaseShield::OnEquipped()
{
SetIsEquipped(true);
AActor* owner = GetOwner();
if (!owner)
return;
CombatComponent = owner->GetComponentByClass<UCombatComponent>();
CombatComponent->OnCombatToggled.AddUObject(this, &ABaseWeapon::ToggleWeaponCombat);
OwnerStateManager = owner->GetComponentByClass<UStateManagerComponent>();
if (CombatComponent->GetCombatEnabled())
AttachActor(HandSocketName);
else
AttachActor(AttachSocketName);
CombatComponent->SetShieldWeapon(this);
CollisionComponent->SetCollisionMeshComponent(GetItemMesh());
CollisionComponent->AddActorToIgnore(GetOwner());
}
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

@ -1,25 +0,0 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Actor/BaseWeapon.h"
#include "BaseShield.generated.h"
/**
*
*/
UCLASS()
class D1_API ABaseShield : public ABaseWeapon
{
GENERATED_BODY()
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

@ -145,6 +145,8 @@ TArray<UAnimMontage*> ABaseWeapon::GetActionMontage(FGameplayTag characterAction
outputArr.Add(EnterCombat);
else if (FCombatGameplayTags::Get().Character_Action_ExitCombat == characterAction)
outputArr.Add(ExitCombat);
else if (FCombatGameplayTags::Get().Character_Action_Attack_Blocking == characterAction)
outputArr = BlockAttackMontage;
return outputArr;
}

View File

@ -77,6 +77,8 @@ protected:
TArray<TObjectPtr<UAnimMontage>> FallingAttackMontage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Montages")
TArray<TObjectPtr<UAnimMontage>> SprintAttackMontage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Montages")
TArray<TObjectPtr<UAnimMontage>> BlockAttackMontage;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Status")
float Damage;

View File

@ -3,9 +3,12 @@
#include "Actor/PickupActor.h"
#include "Actor/BaseEquippable.h"
#include "Components/EquipmentComponent.h"
#include "Components/SceneComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Components/SphereComponent.h"
#include "Particles/ParticleSystemComponent.h"
// Sets default values
APickupActor::APickupActor()
@ -18,24 +21,17 @@ APickupActor::APickupActor()
Cube = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Cube"));
Cube->SetupAttachment(RootComponent);
Sphere = CreateDefaultSubobject<USphereComponent>(TEXT("Sphere"));
Sphere->SetupAttachment(Cube);
Sphere->SetupAttachment(RootComponent);
ParticleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("ParticleSystem"));
ParticleSystem->SetupAttachment(RootComponent);
}
void APickupActor::Interact(AActor* Caller)
{
if (Caller == nullptr)
return;
APawn* pawn = Cast<APawn>(Caller);
if (pawn != nullptr)
{
FActorSpawnParameters spawnParam;
spawnParam.Owner = Caller;
spawnParam.Instigator = pawn;
ABaseEquippable* SpawnItem = Cast<ABaseEquippable>(GetWorld()->SpawnActor(Item, &GetActorTransform(), spawnParam));
if (SpawnItem)
SpawnItem->OnEquipped();
}
Caller->GetComponentByClass<UEquipmentComponent>()->EquipItem(ItemClass);
}

View File

@ -21,14 +21,17 @@ public:
private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
TObjectPtr<class USceneComponent> DefaultSceneRoot;
TObjectPtr<USceneComponent> DefaultSceneRoot;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
TObjectPtr<class UStaticMeshComponent> Cube;
TObjectPtr<UStaticMeshComponent> Cube;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
TObjectPtr<class USphereComponent> Sphere;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
TObjectPtr<UParticleSystemComponent> ParticleSystem;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Components", meta=(AllowPrivateAccess="true"))
TSubclassOf<class ABaseEquippable> Item;
TSubclassOf<class ABaseEquippable> ItemClass;
};

View File

@ -0,0 +1,51 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Actor/SwordAndShield.h"
#include "Components/CombatComponent.h"
#include "GameFramework/Character.h"
ASwordAndShield::ASwordAndShield()
{
ShieldMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ShieldMesh"));
ShieldMesh->SetupAttachment(RootComponent);
ShieldMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}
void ASwordAndShield::ToggleWeaponCombat(bool EnableCombat)
{
Super::ToggleWeaponCombat(EnableCombat);
if(EnableCombat)
AttachShield(ShieldHandSocket);
else
AttachShield(ShieldAttachSocket);
}
void ASwordAndShield::OnEquipped()
{
Super::OnEquipped();
if (CombatComponent->GetCombatEnabled())
AttachShield(ShieldHandSocket);
else
AttachShield(ShieldAttachSocket);
CombatComponent->SetShieldEquipped(true);
}
void ASwordAndShield::OnUnequipped()
{
Super::OnUnequipped();
CombatComponent->SetShieldEquipped(false);
}
void ASwordAndShield::AttachShield(FName attachSocket)
{
ACharacter* pCharacter = Cast<ACharacter>(GetOwner());
if(pCharacter)
{
FAttachmentTransformRules rules(EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, true);
ShieldMesh->AttachToComponent(pCharacter->GetMesh(), rules, attachSocket);
}
}

View File

@ -0,0 +1,32 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Actor/BaseWeapon.h"
#include "SwordAndShield.generated.h"
/**
*
*/
UCLASS()
class D1_API ASwordAndShield : public ABaseWeapon
{
GENERATED_BODY()
public:
ASwordAndShield();
public:
virtual void ToggleWeaponCombat(bool EnableCombat) override;
virtual void OnEquipped() override;
virtual void OnUnequipped() override;
public:
void AttachShield(FName attachSocket);
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Mesh", meta=(AllowPrivateAccess="true"))
TObjectPtr<UStaticMeshComponent> ShieldMesh;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization", meta = (AllowPrivateAccess = "true"))
FName ShieldAttachSocket;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Initialization", meta = (AllowPrivateAccess = "true"))
FName ShieldHandSocket;
};

View File

@ -913,9 +913,9 @@ bool ACombatPlayerCharacter::PerformKnockdown()
bool ACombatPlayerCharacter::PerformBlock()
{
if(!IsValid(CombatComponent->GetShieldWeapon()))
if(!IsValid(CombatComponent->GetMainWeapon()))
return false;
TArray<UAnimMontage*> hitMontage = CombatComponent->GetShieldWeapon()->GetActionMontage(FCombatGameplayTags::Get().Character_Action_Attack_Blocking);
TArray<UAnimMontage*> hitMontage = CombatComponent->GetMainWeapon()->GetActionMontage(FCombatGameplayTags::Get().Character_Action_Attack_Blocking);
if(hitMontage.Num() <= 0)
return false;
@ -1021,7 +1021,7 @@ bool ACombatPlayerCharacter::CanPerformBlock()
ReturnValue &= !StateManagerComponent->IsCurrentStateEqualToAny(inputContainer);
ReturnValue &= CombatComponent->GetCombatEnabled();
ReturnValue &= IsValid(CombatComponent->GetShieldWeapon());
ReturnValue &= CombatComponent->GetShieldEquipped();
ReturnValue &= bIsBlockPressed; //Block Key를 눌렀는가?
return ReturnValue;

View File

@ -38,9 +38,10 @@ 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; }
FORCEINLINE bool GetIsBlocking() { return bIsBlocking; }
FORCEINLINE void SetShieldEquipped(bool isEquipped) { bIsShieldEquipped = isEquipped; }
FORCEINLINE bool GetShieldEquipped() { return bIsShieldEquipped; }
private:
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true"))
@ -54,13 +55,11 @@ private:
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true"))
int32 AttackCount;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true"))
TObjectPtr<ABaseWeapon> EquippedShield;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess="true"))
bool bIsBlocking;
bool bIsShieldEquipped;
public: //Delegate
FOnCombatToggled OnCombatToggled;
FOnBlockingSet OnBlockingSet;

View File

@ -36,37 +36,15 @@ void UEquipmentComponent::TickComponent(float DeltaTime, ELevelTick TickType, FA
void UEquipmentComponent::InitializeEquipment()
{
for (auto item : EquippedItems)
UnequipItem(item);
for (auto equipment : StartingEquipment)
{
if(!IsValid(equipment.Get()))
continue;
AActor* owner = GetOwner();
if(!IsValid(owner))
continue;
APawn* ownerPawn = Cast<APawn>(owner);
if(!IsValid(ownerPawn))
continue;
FActorSpawnParameters SpawnParameters;
SpawnParameters.Owner = owner;
SpawnParameters.Instigator = ownerPawn;
ABaseEquippable* EquipInstance = Cast<ABaseEquippable>(GetWorld()->SpawnActor(equipment, &owner->GetActorTransform(), SpawnParameters));
if(EquipInstance)
{
EquippedItems.AddUnique(EquipInstance);
EquipInstance->OnEquipped();
//Player have Weapon until first time : probably temp coding
if(ACombatPlayerCharacter* Player = Cast<ACombatPlayerCharacter>(GetOwner()))
{
if(ABaseConsumable* consumableItem = Cast<ABaseConsumable>(EquipInstance))
{
if(UUI_PotionAmountText* PotionAmountText = Cast<UUI_PotionAmountText>(Player->PotionUI))
PotionAmountText->InitializePotionData(consumableItem); //TODO : [UMG] 관련 부분 구조 변경 필요
}
}
}
EquipItem(equipment);
}
}
@ -89,6 +67,43 @@ bool UEquipmentComponent::PerformActionFromItem(FGameplayTag ItemTag)
return false;
}
bool UEquipmentComponent::EquipItem(TSubclassOf<ABaseEquippable> InEquipment)
{
if(!IsValid(InEquipment->GetClass()))
return false;
for (auto item : EquippedItems)
{
if(item.GetClass() == InEquipment)
UnequipItem(item);
}
AActor* owner = GetOwner();
APawn* pawn = Cast<APawn>(owner);
if (pawn == nullptr)
return false;
FActorSpawnParameters spawnParam;
spawnParam.Owner = owner;
spawnParam.Instigator = pawn;
ABaseEquippable* SpawnItem = Cast<ABaseEquippable>(GetWorld()->SpawnActor(InEquipment, &owner->GetActorTransform(), spawnParam));
if (SpawnItem)
{
SpawnItem->OnEquipped();
EquippedItems.AddUnique(SpawnItem);
}
return true;
}
void UEquipmentComponent::UnequipItem(ABaseEquippable* EquipmentToUnequip)
{
if(IsValid(EquipmentToUnequip))
{
EquipmentToUnequip->OnUnequipped();
EquipmentToUnequip->Destroy(); //TODO : 현재는 장비를 해제하면 파괴함 임시처리
}
}
ABaseEquippable* UEquipmentComponent::GetEquippedItemByTag(FGameplayTag itemTag)
{
for (auto Item : EquippedItems)

View File

@ -29,6 +29,9 @@ public:
public:
void InitializeEquipment();
bool PerformActionFromItem(FGameplayTag ItemTag);
bool EquipItem(TSubclassOf<ABaseEquippable> InEquipment);
void UnequipItem(ABaseEquippable* EquipmentToUnequip);
UFUNCTION(BlueprintCallable)
ABaseEquippable* GetEquippedItemByTag(FGameplayTag itemTag);