티스토리 뷰
Gameplay Ability System - Top Down RPG / Section 8-31
Just Move 2026. 6. 29. 05:17Mapping Tags to Attributes
현재는 Strength 속성만 처리 중이며, 기존 방식을 따르면 속성마다 동일한 작업을 반복해야 한다.
따라서 위젯 컨트롤러에서는 속성이 몇 개인지, 이름이 무엇인지 신경 쓰지 않고 모든 숙성을 자동으로 순회하며 브로드캐스트하는 구조를 만들 것이다.
이를 위해서 Map 자료 구조를 활용할 것이다.
키는 GameplayTag로, 값은 GameplayAttribute가 되도록 매핑한다.
Attribute Set에는 각 속성에 접근할 수 있는 Attribute Accessor가 존재하고, 이 함수들이 GameplayAttribute를 반환한다.
하지만 이러면 함수 자체를 연결해서 저장해야하는 상황이지만, 함수는 일반 값처럼 저장할 수 없기 때문에 Delegate를 활용해줄 것이다.
우리는 값이 필요하므로, 반환값이 있는 Delegate를 활용한다.

그리고 Delegate 타입을 참고하여, Map 또한 이어서 작성해준다.

이제 생성자에서 Map에 값을 넣어주자.
우선 테스트로 Strength와 Intelligence만 할당하였다.

이제 위젯컨트롤러로 가서 해당 Map을 순회할 것이다.
여기서 Key는 GameplayTag고, Value는 Delegate를 통해 호출된 값이다.
Delegat에는 FGameplayAttribute 핸들이 있는 것이기 때문에, GetNumericValue 함수를 통해 실제 Float 값을 꺼내준다.

이 상태로 컴파일을 해보면 정상적으로 Strength와 Intelligence 값이 할당된 것을 볼 수 있다.

근데 따지고 보면 현재도 위치가 다를 뿐, 코드가 여전히 비효율적이고 반복되는 과정을 작성해야 한다.
따라서 Delegate를 없애고, 정적 함수 자체를 Map에 바로 넣을 수 있는지 확인해볼 것이다.
우리가 쓰는 것은 Attribute Accessor 함수이며, 이 함수들은 입력값이 없고 FGameplayAttribute를 반환한다.
즉, 함수 시그니처는 FGameplayAttribute()로 동일하다.
따라서 이 시그니처를 가진 함수들을 저장하는 함수 포인터 타입을 하나 정의하면, 모든 Accessor 함수를 동일한 타입으로 관리하고 Map에 저장할 수 있다.
그리고 추가로 BindStatic() 함수의 내부를 보면 매우 복잡한 템플릿 타입이 등장한다.
이 타입은 정적 함수를 Delegate에 바인딩하기 위한 내부 구조이며, 내부적으로 정적 함수의 주소를 저장하기 위해 함수 포인터 타입을 사용한다.
해당 템플릿 전체를 완전히 이해할 필요는 없지만, 중요한 것은 내부에서 무엇을 사용하는지이다.
우리가 필요한 것은 결국 GetStrengthAttribute() 같은 정적 함수의 주소를 저장할 수 있는 함수 포인터이다.
TBaseStaticDelegateInstance 내부에는 이 함수 포인터 타입을 나타내는 FFuncPtr가 정의되어 있으므로, 해당 타입을 Map의 Value 타입으로 활용할 수 있다.

그럼 이제 생성자 코드에서 Attribute Accessor 함수를 통해 간단하게 코드를 개선할 수 있다.

위젯에서도 코드를 수정해야 한다.
기존에는 Pair.Value가 Delegate였기 때문에 실행을 위해서 Execute() 함수를 사용했지만, 이제는 바로 Pair.Value()을 사용한다.

추가적으로 auto에서 Value 값을 보면 FGameplayAttribute(*)()라고 뜨는 것을 볼 수 있다.
이러한 함수 포인터 타입으로 바꿔도 정상적으로 작동하지만, 처음 보면 직관적이지 않아 기존 구조를 냅두되, 더 보기 좋은 이름으로 감싸서 사용할 것이다.


그래서 사용하는 것이 typedef를 활용한 별칭 만들기이다.
하지만 typdef로는 오직 하나의 함수 시그니처만 표현할 수 있다.
typedef FGameplayAttribute(*FAttributeFuncPtr)();
반환값 FGameplayAttribute, 입력 값 없음인 함수만 가능
따라서 어떤 함수 시그니처든 받을 수 있도록 using과 template를 활용한 형태를 만들어준다.
T에 원하는 함수 시그니처를 넣으면, 그 함수 포인터 타입으로 사용이 가능하여 확장성이 뛰어나다.
여기서는 Map의 Value로 쓸 FGameplayAttribute()를 사용할 것이다.

이제 속성 추가가 기존에 비해 매우 간단해졌다.
나머지 주요 속성들도 마저 작성해주자.

이제 초기값을 브로드캐스트하는 것은 모두 구현한 상태이다.
하지만 속성 값이 변경되었을 때 UI를 자동 갱신하는 것에 대해서는 아직 불가능하다.
따라서 다음 강의를 통해 Attribute 값 변경을 감지하고, 변경된 속성만 브로드캐스트하여 UI를 실시간 업데이트하는 방법을 다룬다.
'Study > [Unreal] Udemy 강의' 카테고리의 다른 글
| Gameplay Ability System - Top Down RPG / Section 8-30 (0) | 2026.06.28 |
|---|---|
| Gameplay Ability System - Top Down RPG / Section 8-29 (0) | 2026.06.27 |
| Gameplay Ability System - Top Down RPG / Section 8-28 (0) | 2026.06.12 |
| Gameplay Ability System - Top Down RPG / Section 8-27 (0) | 2026.06.11 |
| Gameplay Ability System - Top Down RPG / Section 8-26 (0) | 2026.06.09 |
