게임플레이 능력 시스템 구현
Ability·Effect·AttributeSet과 서버 권한·예측 흐름을 이해하고 비용·쿨다운 적용과 기본 공격의 연결을 구성합니다.
지금까지는 게임 핵심 구조, 플레이어 상태 관리, 세이브/로드 등 기본 프레임워크 요소를 다뤘습니다.
이제는 플레이어/AI 캐릭터의 다양한 행동, 즉 능력(Ability)을 체계적으로 관리하는 방법으로 확장합니다.
언리얼 엔진은 복잡한 스킬/공격/아이템 사용 로직을 다루기 위해 게임플레이 능력 시스템(Gameplay Ability System, GAS)을 제공합니다.
이번 절에서는 GAS의 기본 개념과 주요 구성 요소, 그리고 간단한 구현 예시를 통해 게임플레이 로직 구조화를 살펴봅니다.
게임플레이 능력 시스템(GAS)이란 무엇인가?
게임플레이 능력 시스템 (Gameplay Ability System, GAS)은 언리얼 엔진에서 캐릭터의 스킬, 마법, 공격, 방어, 버프/디버프, 아이템 사용 등 모든 형태의 능력을 모듈화하여 구현하고 관리하기 위한 고수준 프레임워크입니다.
이는 특히 RPG, AOS, FPS 등 복잡한 능력과 스탯, 상태 이상이 많은 게임에 최적화되어 있습니다.
GAS가 필요한 이유- 모듈화 및 재사용성: 각 능력을 독립적인 에셋(Gameplay Ability)으로 정의하여 여러 캐릭터에 재사용하고 관리하기 용이합니다.
- 네트워크 복제 지원: 대부분의 GAS 구성 요소는 네트워크 복제를 기본으로 지원하여 멀티플레이어 게임 개발을 용이하게 합니다.
- 상태 관리 (Gameplay Attributes): 체력, 마나, 공격력 등 캐릭터의 스탯(Attribute)을 중앙에서 관리하고 변경 사항을 효율적으로 복제합니다.
- 상태 이상 및 버프/디버프 (Gameplay Effects): 기절, 중독, 속도 증가 등 다양한 상태 이상 효과를 유연하게 적용하고 해제할 수 있습니다.
- 입력 매핑: 입력(키 누름, 버튼 클릭)과 능력 실행을 유연하게 연결합니다.
- 데이터 주도적 설계: 많은 로직이 데이터 테이블이나 블루프린트 에셋 형태로 관리되어 디자이너의 참여를 확대하고 반복 작업 속도를 높입니다.
GAS의 주요 구성 요소
GAS는 여러 개의 핵심 클래스와 개념들이 유기적으로 결합되어 작동합니다.
UAbilitySystemComponent (능력 시스템 컴포넌트)- GAS에서 능력 실행과 상태 적용을 담당하는 중심 컴포넌트입니다. Pawn/Character 또는 PlayerState 같은 Actor에 둘 수 있습니다. ASC를 소유한 Owner Actor와 실제 능력을 수행하는 Avatar Actor는 다를 수 있습니다.
- 능력 부여/제거, 능력 실행/취소, 속성(Attribute) 변경, 이펙트 적용/해제 등 모든 GAS 관련 기능을 담당합니다.
- 네트워크 복제를 지원하여 서버-클라이언트 간 능력 및 속성 동기화를 처리합니다.
UGameplayAbility (게임플레이 능력)- 단일 능력의 로직을 정의하는 에셋입니다. (예:
GA_Fireball,GA_MeleeAttack,GA_Heal) - 블루프린트로 구현되며, 능력 활성화 조건, 실행 로직, 쿨다운, 소모 비용(마나), 능력 취소 조건 등을 포함합니다.
Ability Tags와 활성화 조건을 정의하고, 입력 이벤트에서 ASC에 활성화를 요청하도록 별도로 연결합니다.
UAttributeSet (게임플레이 속성 세트)- 캐릭터의 스탯(Attributes)을 정의하는 컨테이너 클래스입니다. (예: 체력, 마나, 공격력, 방어력, 속도 등)
UAbilitySystemComponent에 등록하여 사용하며, 멀티플레이에서는 속성의 복제 및 OnRep 처리를 네이티브 클래스에서 구성합니다.FGameplayAttributeData는 기본 값과 현재 값을 가집니다. 최대 체력이 필요하면MaxHealth라는 별도 속성과 제한 정책을 정의합니다.
UGameplayEffect (게임플레이 이펙트)- 속성(Attribute)에 변화를 주거나 태그를 부여/제거하여 캐릭터의 상태를 변화시키는 에셋입니다. (예:
GE_Poison(체력 지속 감소),GE_SpeedBoost(속도 증가),GE_Stun(기절 태그 부여)) - 인스턴트(Instant): 즉시 적용되고 끝나는 효과 (예: 즉시 데미지)
- 지속(Duration): 일정 시간 동안 지속되는 효과 (예: 버프, 독)
- 무한(Infinite): 명시적으로 제거할 때까지 지속되는 효과입니다.
- 주기 적용(Periodic): Duration/Infinite 효과에서 Period를 설정해 반복 적용합니다. 별도의 Duration Policy 종류는 아닙니다.
- 수정자(Modifiers): 속성 값에 직접적인 변화를 줍니다 (덧셈, 곱셈 등).
- 수정자의
Attribute에서 등록된 AttributeSet의 대상 속성을 선택합니다.
FGameplayTagContainer (게임플레이 태그 컨테이너)- 능력, 이펙트, 캐릭터 상태 등을 식별하는 GameplayTag의 집합입니다. 각 태그는 계층적인 이름을 사용합니다. (예:
Ability.Melee,State.Stunned,Buff.Speed) - 태그를 통해 특정 능력이 다른 능력에 의해 차단되거나, 특정 이펙트가 특정 태그를 가진 대상에게만 적용되도록 제어할 수 있습니다.
- 프로젝트 세팅의
Gameplay Tags에서 사용할 태그를 정의합니다.
GAS 핵심 관계 정리: Ability / Effect / AttributeSet
앞의 구성 요소에서 Ability는 실행 흐름, Effect는 값과 태그 변경 규칙, AttributeSet은 속성 저장과 변경 처리를 맡습니다.
실무 규칙- Ability 안에 수치 계산을 하드코딩하기보다 Effect와 태그 규칙으로 분리합니다.
- AttributeSet은 값 보관과 변경 이벤트 처리에 집중하고, UI 갱신은 별도 위젯/컨트롤러에서 처리합니다.
- 쿨다운/코스트는 가능하면
GameplayEffect로 통일해 재사용성을 확보합니다.
멀티플레이어 기준 실행 흐름 (입력, 쿨다운, 코스트, 권한)
- 초기화와 부여: 서버에서 능력을 부여하고 서버·소유 클라이언트의 ASC Actor Info를 올바르게 초기화합니다.
- 활성화 요청: 입력에서 ASC에 요청합니다. 실행 정책에 따라 서버 실행 또는 로컬 예측을 사용하며, 예측 사용만으로 모든 효과가 예측 가능한 것은 아닙니다.
- 커밋: Ability의
Commit Ability결과를 분기합니다. 기본 커밋은 비용·쿨다운을 검사하고 둘을 적용하므로 실패하면 실행을 종료합니다. - 능력 실행: 애니메이션과 타격 판정을 진행하되 최종 피해·대상 검증은 서버에서 합니다.
- 종료와 보정: 완료·취소 경로 모두
End Ability에 도달하도록 하고, GAS가 지원하는 예측 상태의 서버 응답을 반영합니다. 쿨다운을 종료 시 적용하려면 기본 커밋과 구분한 별도 설계가 필요합니다.
- Ability 실행의 진실 소스는 서버로 두고, 클라이언트는 UX를 위한 예측 연출에 집중합니다.
- 비용/쿨다운 실패 시에는 즉시 UI 피드백(아이콘 플래시, 사운드, 텍스트)을 제공합니다.
- 네트워크 규칙은 9장 3절 리플리케이션과 동일한 기준을 따릅니다.
간단한 게임플레이 능력 구현 예시: 기본 공격
플레이어 캐릭터의 근접 공격을 구성합니다. 이 절은 네이티브 GAS 기반 클래스가 준비되어 있다는 전제에서 Blueprint Ability와 Effect 에셋을 연결하는 예제입니다. 기본 엔진의 AttributeSet을 단순 Blueprint Float 변수로 만드는 절차는 아닙니다.
0단계: GAS 모듈 활성화 및 기본 설정플러그인 활성화: 언리얼 에디터에서 편집(Edit) > 플러그인(Plugins)으로 이동하여 GameplayAbilities 플러그인을 찾아 활성화합니다. 네이티브 기반 코드에서는 GameplayAbilities, GameplayTags, GameplayTasks 모듈 의존성도 구성합니다.
에디터를 재시작합니다.
게임플레이 태그 설정: 편집(Edit) > 프로젝트 세팅(Project Settings) > 게임플레이 태그(Gameplay Tags)에서 다음 태그를 추가합니다.
Ability.MeleeState.AttackingEvent.AttackHit(공격 접촉 시점을 전달하기 위해 직접 보낼 이벤트)
BP_MyPlayerCharacter의 기반 클래스에AbilitySystemComponent와UAttributeSet파생 클래스AS_MyCharacterAttributes가 구성되어 있어야 합니다.- 이 속성 세트는
Health와MaxHealth를FGameplayAttributeData로 선언하고 초기값을 각각 100으로 둡니다. 일반 Blueprint Float는 GameplayEffect의 Attribute가 되지 않습니다. - 네이티브 코드에서 속성 복제/OnRep, 등록,
PreAttributeChange와PostGameplayEffectExecute의 범위 제한을 구현합니다. UI는 이 값 변경을 구독합니다. - AttributeSet은 UObject이므로
Spawn Actor of Class로 만들지 않습니다.
- 이 예제는 캐릭터가 ASC를 소유하므로 Owner와 Avatar를 모두 해당 캐릭터로 초기화합니다.
- 서버의 빙의와 클라이언트의 소유 정보 준비 시점에 맞춰 네이티브 기반 코드가
InitAbilityActorInfo를 수행하도록 합니다. 일반 엔진에 이 절의 모든 초기화 함수가 Blueprint 노드로 노출되어 있다고 가정하지 않습니다. IAbilitySystemInterface구현 또는 명시적인 ASC 참조를 제공하여 능력을 사용할 캐릭터의 ASC를 조회합니다. 재빙의 시 Avatar 정보도 갱신합니다.
- 콘텐츠 브라우저에서 마우스 오른쪽 버튼 클릭 >
블루프린트 클래스(Blueprint Class)>All Classes에서GameplayAbility를 검색하여 선택합니다. - 이름을
GA_MeleeAttack으로 지정합니다.
GA_MeleeAttack 설정GA_MeleeAttack블루프린트를 열고,클래스 디폴트(Class Defaults)를 클릭합니다.Ability Tags:Ability.Melee태그 추가.- 비용·쿨다운: 필요하면
Cost Gameplay Effect Class와Cooldown Gameplay Effect Class에 별도로 만든 Effect를 지정합니다. 비용은 준비한 자원 속성을 차감하고, 쿨다운 Effect는 지속 시간과 차단에 사용할 쿨다운 태그를 갖도록 구성합니다. 이 기본 공격은 선택 사항으로 두며, 단순 시간 숫자나Activation Input이름만으로 자동 연결되지 않습니다. -
이벤트 오버라이드
Activate Ability에서Commit Ability의 불리언 결과를 분기합니다. 실패하면 취소로 종료하고, 성공한 경우에만 공격을 진행합니다.- 성공 경로에서
Wait Gameplay Event로Event.AttackHit를 한 번 기다리도록 등록한 뒤,Play Montage and Wait에AM_PlayerAttack을 연결합니다. - 기본
Play Montage and Wait에는 임의의Event Name입력이 없습니다. 몽타주의 타격 Notify 처리에서Send Gameplay Event to Actor로 Avatar에 위 태그를 직접 보내도록 구성합니다. - 완료에는
End Ability, 중단·취소에는 취소 종료를 연결합니다.On End Ability에서 필요한 정리를 합니다.
Wait Gameplay Event의 수신 경로에서 서버가 트레이스/콜리전으로 유효한 적과 거리를 검증하고 대상 데이터를 구성합니다. Notify나 클라이언트가 보낸 대상만으로 피해를 확정하지 않습니다.- 검증한 대상 ASC에
GE_Damage를 한 번 적용합니다. 대상 데이터가 필요하면Ability Target Data from Actor등으로 구성해 해당 Ability의 대상 적용 노드에 전달합니다. - 몽타주의
On Completed나On Blend Out은 접촉 순간을 뜻하지 않습니다. 피해 적용은 위 이벤트 경로에 두고, 완료 경로는 능력 종료에 사용합니다. Apply Gameplay Effect to Owner는 자기 자신에게 적용하는 용도입니다. 적의 피해와 자신의 비용 Effect를 혼동하지 않습니다.
GE_Damage)
- 콘텐츠 브라우저에서 마우스 오른쪽 버튼 클릭 >
블루프린트 클래스(Blueprint Class)>All Classes에서GameplayEffect를 검색하여 선택합니다. - 이름을
GE_Damage로 지정합니다.
GE_Damage 설정GE_Damage블루프린트를 열고클래스 디폴트(Class Defaults)를 클릭합니다.Duration Policy:Instant(즉시 적용)Modifiers:+버튼을 클릭하여 새로운 수정자를 추가합니다.Attribute:Health(AS_MyCharacterAttributes의 Health 속성)Modifier Op:Additive(더하기)Modifier Magnitude: 고정값 예제는Scalable Float에-20.0을 설정합니다.Set by Caller로 바꾸는 경우에도 지정한 데이터 태그에 음수 피해 값(-20.0)을 전달해야 Additive가 체력을 줄입니다. 양수20.0은 체력을 더합니다.
- 컴파일 및 저장합니다.
BP_MyPlayerCharacter 블루프린트 열기- 준비한 네이티브 기반 코드 또는 노출된
Give AbilityAPI를 사용해GA_MeleeAttack을 레벨 1로 한 번 부여합니다. 클라이언트에서 임의로 부여하지 않으며 재빙의 시 중복 부여하지 않습니다. - 여기서는 태그로 활성화하므로 존재하지 않는
Input Tag: Ability1핀을 설정하지 않습니다. 프로젝트 고유의 입력 태그 바인딩은 별도 시스템입니다.
편집(Edit) > 프로젝트 세팅(Project Settings) > 엔진(Engine) > 입력(Input)으로 이동합니다.액션 매핑(Action Mappings): Attack이라는 새 액션 매핑을 추가하고 키를 Left Mouse Button으로 설정합니다.
BP_MyPlayerCharacter의 PlayerController (예: PC_MyPlayer) 열기Event Graph에서Input Action Attack이벤트를 생성합니다.Pressed핀에서Get Controlled Pawn으로 빙의한 캐릭터를 찾고, 유효한 캐릭터의 ASC를 조회합니다. PlayerController 자신에 ASC가 있다고 가정하지 않습니다.AbilitySystemComponent의Try Activate Abilities By Tag노드를 호출합니다.Gameplay Tag Container에Ability.Melee를 넣습니다.Allow Remote Activation은 능력 실행 정책에 맞게 설정합니다. 이 노드에는Ignore Ability Cost나Ignore Cooldown입력이 없습니다.- 반환값은 활성화 시도를 뜻하며 이후 커밋이나 타격 성공까지 보장하지 않습니다.
- 컴파일 및 저장합니다.
테스트 및 디버깅
모든 블루프린트를 컴파일하고 저장합니다.
게임을 플레이하고 Left Mouse Button을 눌러 GA_MeleeAttack이 활성화되고 애니메이션이 재생되는지 확인합니다.
디버그
ShowDebug AbilitySystem: 콘솔에 입력하면 GAS 관련 디버그 정보를 화면에 표시합니다.- 상태 확인: 현재 ASC의 소유자·Avatar, 부여된 Ability, 태그, Health, 커밋 성공/실패를 구분해 확인합니다. 단일 실행과 서버·클라이언트 실행을 따로 기록합니다.
GAS 멀티플레이어에서 자주 발생하는 실수 (Authority / Prediction)
- 서버 검증 누락: 클라이언트에서만 능력 성공 처리를 완료하면 치트/불일치가 발생합니다.
- 코스트-쿨다운 적용 순서 혼동: 코스트 실패인데 쿨다운이 들어가거나, 반대로 쿨다운만 빠지는 버그가 생길 수 있습니다.
- 예측 보정 누락: 클라이언트 예측 결과와 서버 확정 결과가 다를 때 롤백/보정을 하지 않으면 순간이동, 중복 타격처럼 보입니다.
- 태그 충돌 관리 부재:
State.Stunned같은 제약 태그를 통합 관리하지 않으면 스킬 동시 실행 버그가 빈번합니다.
- 단일 플레이에서 Ability/Effect/AttributeSet 흐름이 의도대로 동작하는지 먼저 검증합니다.
- Listen Server 2인 테스트에서 입력-실행-복제 로그를 확인합니다.
- 패킷 지연(네트워크 에뮬레이션) 환경에서 예측/보정 품질을 점검합니다.
ShowDebug AbilitySystem,stat net를 동시에 켜고 병목/불일치 구간을 추적합니다.
GAS의 장점과 복잡성
장점- 강력한 모듈화: 각 능력을 독립적으로 설계하고 테스트할 수 있습니다.
- 네트워크 친화적: 복제 로직이 프레임워크 내에 잘 통합되어 멀티플레이어 개발이 용이합니다.
- 유연한 상태 관리: 속성(Attribute)과 이펙트(Effect)를 통해 복잡한 스탯 및 버프/디버프 시스템을 효과적으로 관리합니다.
- 데이터 주도적: 많은 설정을 데이터로 관리하여 개발 효율성을 높입니다.
- GAS는 학습 곡선이 가파르고 초기 설정이 복잡할 수 있습니다.
- 소규모 프로젝트나 매우 간단한 능력 시스템에는 오버킬(Overkill)일 수 있습니다.
GAS는 언리얼 엔진에서 제공하는 가장 강력한 게임플레이 프레임워크 중 하나이며, 복잡한 RPG, 액션 게임 등에서 유연하고 확장 가능한 능력 시스템을 구축하는 데 필수적입니다.
초기 설정 비용이 있으므로 프로젝트 복잡도에 맞춰 GAS 도입 여부를 판단해야 합니다.
이번 절에서는 언리얼 엔진의 게임플레이 능력 시스템(GAS)의 기본 개념, 주요 구성 요소, 그리고 간단한 능력 구현 예시를 통해 GAS가 어떻게 게임플레이 로직을 구조화하고 관리하는지 알아보았습니다.
GAS는 강력하고 유연한 능력을 구현하는 데 필수적인 프레임워크입니다.
이로써 9장 게임플레이 프레임워크의 모든 내용을 마쳤습니다.