팀프로젝트, 개인 연습 프로젝트, 알고리즘 1문제
언리얼 C++에서 FoundSound->Get()처럼 Get()을 호출하는 구조는 보통 래퍼 객체 안에 들어있는 실제 객체를 꺼내기 위해 사용한다.
FoundSound가 단순한 USoundBase*라면 보통 바로 사용할 수 있다.
USoundBase* Sound = FoundSound->Get(); // 실제 UObject 포인터 반환
GAS(Gameplay Ability System)는 단순히 스킬을 실행하는 기능이 아니라, 스킬, 버프, 디버프, 스탯, 쿨타임, 태그를 구조적으로 관리하기 위한 시스템이다.
단순히 “스킬 실행 기능”이 아니라, 캐릭터의 능력과 상태 변화를 하나의 규칙으로 묶어주는 시스템에 가깝다.
FGameplayAttributeData는 GAS에서 Attribute 값을 저장할 때 사용하는 구조체다.
GAS에서 Attribute는 캐릭터의 능력치를 관리하는 곳 이라고 보면 된다.
보통 float Health, float AttackPower이렇게 관리하지만
UPROPERTY(BlueprintReadOnly)
FGameplayAttributeData Health;
UPROPERTY(BlueprintReadOnly)
FGameplayAttributeData AttackPower;
GAS에서는 보통 이렇게 만든다.
이유는 GAS가 Attribute 값을 단순 숫자가 아니라 효과 적용, 버프, 디버프, 복제, 계산 흐름과 연결해서 관리하기 때문이다.
FGameplayAttributeData 안에는 대표적으로 두 값이 있다.
BaseValue는 기본값.
AttackPower BaseValue = 100
현재 실제 적용 중인 값이다.
버프나 디버프가 걸리면 CurrentValue가 달라질 수 있다.
기본 공격력 100
공격력 증가 버프 +20%
AttackPower BaseValue = 100
AttackPower CurrentValue = 120
즉, FGameplayAttributeData는 단순한 float 자료형보다 GAS형식으로 맞는 능력치 저장 방식이다. GAS를 사용할때는 HP, 공격력, 이동속도 같은 주요 스탯은 float보다 FGameplayAttributeData로 만드는 경우가 많다.
ASC는 AbilitySystemComponent의 줄임말이다.
GAS에서 ASC는 핵심 엔진이라고 말할 정도로 중요하다. ASC는 캐릭터가 가지고 있는 능력 시스템 관리자이다.
ASC가 담당하는 것은 다음과 같다.
GAS에서는 보통 ASC를 외부에서 가져올 수 있도록 인터페이스를 사용한다.
public IAbilitySystemInterface
Input 입력
→ ASC가 Ability 실행 요청
→ Ability가 발동 조건 확인
→ GameplayEffect 적용
→ Attribute 변경
→ GameplayTag / Cooldown 처리
AttributeSet은 GAS에서 Attribute들을 모아두는 클래스이다. 아까 설명했던 FGameplayAttributeData들을 관리한다.
왜 굳이 따로 만드냐면, ASC가 이 AttributeSet을 참조해서 능력치를 관리하기 때문이다.
구조
PlayerCharacter 또는 PlayerState
├─ AbilitySystemComponent
└─ AttributeSet
├─ Health
├─ MaxHealth
├─ AttackPower
└─ MoveSpeed
ASC는 "능력 시스템 관리자"이고, AttributeSet은 "능력치 데이터 묶음"이다.
ASC
→ 능력, 효과, 태그, 쿨타임을 관리하는 시스템
AttributeSet
→ ASC가 변경할 수 있는 능력치 데이터
예를 들어 공격력 증가 효과가 들어오면
GameplayEffect 적용
→ ASC가 효과 계산
→ AttributeSet의 AttackPower 변경
피격을 당하면
Damage GameplayEffect 적용
→ ASC가 Health 감소 처리
→ AttributeSet의 Health 변경