0. 개요
스펠 장착 버튼을 생성하고 스펠 메뉴에 추가한다.
위젯 컨트롤러 코드를 리펙토링한다.
1. 스펠 장착 버튼
(1) WBP_WideButton 배치
2. 위젯 컨트롤러 리펙토링
AuraWidgetController를 상속받는 위젯 컨트롤러를 생성한다.
(1) OverlayWidgetController의 델리게이트를 부모인 AuraWidgetController로 이전
오버레이 위젯 컨트롤러가 사용하던 AbilityInfo 델리게이트를 부모로 이전해서 다른 위젯 컨트롤러도 이용할 수 있게 할 것이다.
이는 스펠 메뉴에서도 어빌리티 정보 구조체를 활용할 것이기 때문이다.
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityInfoSignature, const FAuraAbilityInfo&, Info);
class AURA_API UAuraWidgetController : public UObject
{
GENERATED_BODY()
public:
//~~~~~~~~~~~~~~~~~~
UPROPERTY(BlueprintAssignable, Category = "GAS|Messages")
FAbilityInfoSignature AbilityInfoDelegate;
(2) AuraWidgetController에 멤버 변수 추가
이제 이 클래스를 상속받는 모든 클래스가 더이상 GAS의 변수를 가져와 캐스팅하여 사용하는 것이 아니라, 멤버 변수로 직접 접근할 수 있도록 변경할 것이다.
- 종속성 문제
GAS의 구성 요소를 커스텀화한 'Aura' 버전들은 이미 프로젝트 내에서 전반적으로 사용되고 있고 일종의 시스템화가 되으며, 종속성이 일방적이기 때문에 문제가 없다.
protected:
// 종속성 설정
// 플레이어 스테이트 , 플레이어 컨트롤러, 속성 세트, 어빌리티 시스템 컴포넌트
UPROPERTY(BlueprintReadOnly, Category="WidgetController")
TObjectPtr<APlayerController> PlayerController;
UPROPERTY(BlueprintReadOnly, Category="WidgetController")
TObjectPtr<APlayerState> PlayerState;
UPROPERTY(BlueprintReadOnly, Category="WidgetController")
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
UPROPERTY(BlueprintReadOnly, Category="WidgetController")
TObjectPtr<UAttributeSet> AttributeSet;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<AAuraPlayerController> AuraPlayerController;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<AAuraPlayerState> AuraPlayerState;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<UAuraAbilitySystemComponent> AuraAbilitySystemComponent;
UPROPERTY(BlueprintReadOnly, Category = "WidgetController")
TObjectPtr<UAuraAttributeSet> AuraAttributeSet;
// Get Aura PlayerController
AAuraPlayerController* GetAuraPC();
// Get Aura PlayerState
AAuraPlayerState* GetAuraPS();
// Get Aura AbilitySystemComponent
UAuraAbilitySystemComponent* GetAuraASC();
// Get Aura AttributeSet
UAuraAttributeSet* GetAuraAS();
};
Aura 버전의 GAS 구성요소들과 Getter 함수를 선언한다.
#include "Player/AuraPlayerController.h"
#include "Player/AuraPlayerState.h"
#include "AbilitySystem/AuraAbilitySystemComponent.h"
#include "AbilitySystem/AuraAttributeSet.h"
AAuraPlayerController* UAuraWidgetController::GetAuraPC()
{
if (AuraPlayerController == nullptr)
{
AuraPlayerController = Cast<AAuraPlayerController>(PlayerController);
}
return AuraPlayerController;
}
AAuraPlayerState* UAuraWidgetController::GetAuraPS()
{
if (AuraPlayerState == nullptr)
{
AuraPlayerState = Cast<AAuraPlayerState>(PlayerState);
}
return AuraPlayerState;
}
UAuraAbilitySystemComponent* UAuraWidgetController::GetAuraASC()
{
if (AuraAbilitySystemComponent == nullptr)
{
AuraAbilitySystemComponent = Cast<UAuraAbilitySystemComponent>(AbilitySystemComponent);
}
return AuraAbilitySystemComponent;
}
UAuraAttributeSet* UAuraWidgetController::GetAuraAS()
{
if (AuraAttributeSet == nullptr)
{
AuraAttributeSet = Cast<UAuraAttributeSet>(AttributeSet);
}
return AuraAttributeSet;
}
없으면 생성하고 있으면 반환하는 Getter 함수이다.
이제부터는 GAS의 기본 구성 요소를 Aura 버전으로 캐스팅하지 않고 직접 Get하여 사용할 수 있다.
AuraWidgetController의 자식 클래스의 코드를 모두 수정하여 캐스팅 부분을 Getter로 대체한다.
(3) OverlayWidgetController 클래스의 OnInitializeStartupAbilities 함수 이전
OnInitializeStartupAbilities 함수는 모든 어빌리티를 순회하여 해당 어빌리티의 정보를 가져와 블루프린트로 전달하는 역할을 하고 있다.
이 함수의 이름을 바꾸고 상위 클래스인 AuraWidgetController로 옮겨 SpellMenuWidgetController에서도 해당 함수를 활용할 것이다.
void UAuraWidgetController::BroadcastAbilityInfo()
{
// 어빌리티가 주어지지 않았다면 리턴
if (!GetAuraASC()->bStartupAbilitiesGiven)
return;
// 어빌리티를 순회하지 않고 델리게이트를 사용
// 콜백 함수 바인딩
FForEachAbility BroadcastDelegate;
BroadcastDelegate.BindLambda([this](const FGameplayAbilitySpec& AbilitySpec)
{
// TODO : 태그를 이용해서 어빌리티 정보 가져오기
FAuraAbilityInfo Info = AbilityInfo->FindAbilityInfoForTag(GetAuraASC()->GetAbilityTagFromSpec(AbilitySpec));
Info.InputTag = GetAuraASC()->GetInputTagFromSpec(AbilitySpec);
// 블루프린트 델리게이트
AbilityInfoDelegate.Broadcast(Info);
});
// 델리게이트 실행
GetAuraASC()->ForEachAbility(BroadcastDelegate);
}
그리고 OverlayWidgetController에서도 상속된 함수를 이용할 것이다.
if (GetAuraASC())
{
if (GetAuraASC()->bStartupAbilitiesGiven)
{
// 콜백 함수 바인드 필요 없이 바로 호출
BroadcastAbilityInfo();
}
else
{
// 어빌리티 부여 이전이면 델리게이트에 함수 바인딩
GetAuraASC()->AbilitiesGivenDelegate.AddUObject(this, &UOverlayWidgetController::OnInitializeStartupAbilities);
}
기존의 OnInitializeStartupAbilities 함수 호출을 상속받은 BroadcastAbilityInfo 호출로 변경한다.
(3-1) AuraAbilitySystemComponent
한편 위의 코드 블럭에서 AbilitiesGiven 델리게이트를 AuraASC에서 가져와 바인딩하는 것을 볼 수 있다.
DECLARE_MULTICAST_DELEGATE_OneParam(FAbilitiesGiven, UAuraAbilitySystemComponent*);
이제는 각 WidgetController에서 직접 Aura버전의 구성요소를 가져와 쓸 수 있으므로 델리게이트도 변경한다.
DECLARE_MULTICAST_DELEGATE(FAbilitiesGiven);
코드 이전이 완료되었으면 오버레이 위젯 컨트롤러 클래스에서 해당 코드를 제거한다.
이제 스펠 메뉴 위젯 컨트롤러에서 어빌리티 정보에 접근할 수 있게 되었다.
(커스텀 GAS 구성요소에 Getter를 사용하여 직접 접근할 수도 있게 되었다)
'UE 5 스터디 > Gameplay Ability System(GAS)' 카테고리의 다른 글
22-7. 스펠 메뉴 UI - (7) 스펠이 장착된 버튼 (0) | 2025.02.04 |
---|---|
22-6. 스펠 메뉴 UI - (6) 스펠 메뉴 위젯 컨트롤러와 Getter, meta = DefaultToSelf (0) | 2025.01.23 |
22-4. 스펠 메뉴 UI - (4) 메뉴 앵커를 활용한 팝업 메뉴 (0) | 2025.01.22 |
22-3. 스펠 메뉴 UI - (3) 스펠 메뉴 위젯, 스펠 설명 박스 (0) | 2025.01.22 |
22-2. 스펠 메뉴 UI - (2) 스펠 장착 행(Equipped Spell Row) (0) | 2025.01.22 |