🎮 FBFPlayerWeaponData;
USTRUCT(BlueprintType) struct FBFPlayerWeaponData { GENERATED_BODY() UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (TitleProperty = "InputTag")) TArray<FBFAbilitySet>WeaponAbilities; };FBFPlayerWeaponData구조체를 작성하여 필요한 정보를 추가해주었다. 앞으로 무기의 기본 공격력이나, 추가적인 Data가 필요하면 해당 구조체에 추가해주면 될듯 하다.
🎮 APlayerWeapon.h
UCLASS() class BOSSFIGHT_API APlayerWeapon : public AWeaponBase { GENERATED_BODY() public: void AssignGrantAbilitySpecHandles(const TArray<FGameplayAbilitySpecHandle>& InSpecHandles); TArray<FGameplayAbilitySpecHandle>GetGrantAbilitySpecHandle() const; UPROPERTY(EditAnywhere, BlueprintReadOnly) FBFPlayerWeaponData WeaponData; private: TArray<FGameplayAbilitySpecHandle>GrantAbilitySpecHandles; };🎮 APlayerWeapon.cpp
void APlayerWeapon::AssignGrantAbilitySpecHandles(const TArray<FGameplayAbilitySpecHandle>& InSpecHandles) { GrantAbilitySpecHandles = InSpecHandles; } TArray<FGameplayAbilitySpecHandle> APlayerWeapon::GetGrantAbilitySpecHandle() const { return GrantAbilitySpecHandles; }AssignGrantAbilitySpecHandles()함수를 통해 부여된 Ability를 저장하고 GetGrantAbilitySpecHandle()를 통해 저장된 배열을 반환 하도록 함수를 작성 하였다.
🎮 UBFAbilitySystemComponent.cpp
void UBFAbilitySystemComponent::GrantPlayerWeaponAbilities(const TArray<FBFAbilitySet>& PlayerWeaponAbilities, TArray<FGameplayAbilitySpecHandle>& OutGrantAbilitySpecHandles, int32 ApplyLevel) { if (PlayerWeaponAbilities.IsEmpty()) { return; } for (const FBFAbilitySet& AbilitySet : PlayerWeaponAbilities) { if (!AbilitySet.IsVaild()) continue; FGameplayAbilitySpec AbilitySpec(AbilitySet.AbilityToGrant); AbilitySpec.SourceObject = GetAvatarActor(); AbilitySpec.Level = ApplyLevel; AbilitySpec.DynamicAbilityTags.AddTag(AbilitySet.InputTag); OutGrantAbilitySpecHandles.AddUnique(GiveAbility(AbilitySpec)); } } void UBFAbilitySystemComponent::RemoveGrantPlayerWeaponAbilities(TArray<FGameplayAbilitySpecHandle>& InSpecHandleToRemove) { if (InSpecHandleToRemove.IsEmpty()) return; for (FGameplayAbilitySpecHandle& SpecHandle : InSpecHandleToRemove) { if (SpecHandle.IsValid()) { ClearAbility(SpecHandle); } } InSpecHandleToRemove.Empty(); }GrantPlayerWeaponAbilities() 함수로 Ability를 부여 해주고 OutGrantAbilitySpecHandles에 추가하여Out매개변수로 내보내주고 있다.
RemoveGrantPlayerWeaponAbilities() 함수에서는 AbilitySpceHandle를 통해 SpecHandle이 유효하면 제거해주도록 기능을 구현 하였다.
🎮 UPlayerEquipmentComponent.cpp
void UPlayerEquipmentComponent::RegisterWeapon(TArray<AWeaponBase*> NewWeapon) { ABFPlayerCharacter* Owner = Cast<ABFPlayerCharacter>(GetOwner()); UBFAbilitySystemComponent* ASC = Owner->GetBFAbilitySystemComponent(); if (!CurrentWeaponMap.IsEmpty()) { for (TPair Pair : CurrentWeaponMap) { // 저장된 AbilitySpecHanlde을 통해 부여되어 있던 Ability 제거 APlayerWeapon* PlayerWeapon = Cast<APlayerWeapon>(Pair.Value); TArray<FGameplayAbilitySpecHandle> SpecHandles = PlayerWeapon->GetGrantAbilitySpecHandle(); ASC->RemoveGrantPlayerWeaponAbilities(SpecHandles); Pair.Value->Destroy(); } CurrentWeaponMap.Empty(); } for (AWeaponBase* Weapon : NewWeapon) { CurrentWeaponMap.Add(Weapon->GetWeaponType(), Weapon); // Ability부여 및 부여된 Ability의 SpecHandle을 저장 APlayerWeapon* PlayerWeapon = Cast<APlayerWeapon>(Weapon); TArray<FGameplayAbilitySpecHandle> SpecHandles; ASC->GrantPlayerWeaponAbilities(PlayerWeapon->WeaponData.WeaponAbilities, SpecHandles); PlayerWeapon->AssignGrantAbilitySpecHandles(SpecHandles); } UBFFunctionLibrary::AddGameplayTagToActorIfNone(GetOwner(), BFGameplayTag::Player_WeaponEquip); }위와 같이 RegisterWeapon()함수를 수정 해주었다.
