언리얼 엔진

[언리얼 엔진] GAS 기본 구성 요소 정리

dhlee-dev 2026. 6. 17. 21:55

최근 Udemy 강의를 보면서 언리얼 엔진의 Gameplay Ability System, 줄여서 GAS를 실습해보았다.

아직 개인 프로젝트에 직접 적용한 것은 아니지만,
실습을 진행하면서 GAS가 어떤 구조로 동작하는지 조금씩 이해할 수 있었다.

처음에는 Ability, Effect, Attribute, Tag, Cue 같은 용어들이 한꺼번에 나와서 복잡하게 느껴졌다.

하지만 정리해보니 GAS는 캐릭터의 능력, 수치, 상태, 효과, 연출을
각각의 역할로 나누어 관리하기 위한 시스템이라고 볼 수 있었다.

이번 글에서는 GAS를 깊게 다루기보다는,
GAS를 구성하는 기본 요소들이 어떤 역할을 하는지 간단히 정리해보려고 한다.


GAS란?

GAS(Gameplay Ability System)는 언리얼 엔진에서 제공하는 게임플레이 능력 시스템이다.

공격, 회피, 스킬 같은 행동을 Ability로 만들고,
체력 감소, 버프, 디버프 같은 수치 변화를 GameplayEffect로 처리하며,
체력, 마나, 스태미너 같은 값은 Attribute로 관리할 수 있다.

즉, 캐릭터의 행동과 상태 변화를 하나의 흐름으로 관리할 수 있게 해주는 시스템이다.

예를 들어 공격 스킬을 사용한다고 하면 다음과 같은 흐름으로 생각할 수 있다.

GameplayAbility 실행
-> GameplayEffect 적용
-> Attribute 변경
-> GameplayCue로 이펙트나 사운드 재생

물론 실제 구조는 더 복잡하지만,
처음에는 이렇게 Ability, Effect, Attribute, Cue가 연결된다고 보면 이해하기 쉬웠다.


GAS의 주요 구성 요소

GAS를 공부하면서 가장 먼저 정리해야 할 요소는 다음과 같다.

구성 요소 역할
AbilitySystemComponent Ability, Effect, Attribute, Tag를 관리하는 중심 컴포넌트
GameplayAbility 공격, 회피, 스킬 같은 실제 행동
GameplayEffect 데미지, 회복, 버프, 디버프, 쿨타임 같은 효과
AttributeSet 체력, 마나, 스태미너 같은 수치
GameplayTag 상태, 입력, Ability, Effect를 구분하는 표식
GameplayCue 이펙트, 사운드, 카메라 흔들림 같은 연출

각 요소는 따로 존재하는 것이 아니라 서로 연결되어 동작한다.

예를 들어 공격 Ability가 실행되면, 대상에게 데미지 GameplayEffect를 적용하고,
그 결과 Health Attribute가 감소할 수 있다.

그리고 필요한 경우 GameplayCue를 통해 피격 이펙트나 사운드를 재생할 수 있다.


AbilitySystemComponent

AbilitySystemComponent, 줄여서 ASC는 GAS의 중심이 되는 컴포넌트이다.
ASC는 캐릭터가 가진 Ability, 적용 중인 GameplayEffect, GameplayTag, Attribute 등을 관리한다.

간단히 말하면 GAS의 실행을 조율하는 관리자라고 볼 수 있다.

예를 들어 특정 입력이나 태그를 기준으로 Ability를 실행하려고 하면,
ASC가 가진 AbilitySpec 목록에서 실행할 Ability를 찾고 실행을 시도할 수 있다.

입력 또는 GameplayTag 처리
-> ASC의 AbilitySpec 목록에서 실행할 Ability 검색
-> TryActivateAbility 호출
-> GameplayAbility 실행

GameplayAbility

GameplayAbility는 캐릭터가 수행할 수 있는 행동 단위이다.
예를 들어 다음과 같은 것들을 Ability로 만들 수 있다.

  • 기본 공격
  • 회피
  • 스킬 사용
  • 피격 반응
  • 사망 처리

처음에는 Ability를 단순히 “스킬”이라고 생각하기 쉬웠다.

하지만 실습을 해보니 꼭 공격 스킬만 의미하는 것은 아니었다.
피격 반응이나 사망 처리처럼 게임플레이 동작 하나를 Ability로 분리할 수도 있었다.

즉, GameplayAbility는 캐릭터가 수행하는 행동을 독립적인 단위로 분리하기 위한 클래스라고 볼 수 있다.


GameplayEffect

GameplayEffect는 Attribute를 변경하거나 GameplayTag를 부여하는 효과이다.
대표적으로 다음과 같은 상황에 사용할 수 있다.

  • 체력 감소
  • 체력 회복
  • 스태미너 소모
  • 공격력 증가
  • 상태 태그 부여
  • 쿨타임 적용

GAS에서는 보통 Health 값을 직접 깎기보다는
GameplayEffect를 통해 Attribute를 변경하는 흐름을 사용한다.

예를 들어 데미지를 적용한다면 다음과 같은 흐름으로 생각할 수 있다.

공격 Ability 실행
-> 데미지 GameplayEffect 생성
-> 대상 ASC에 GameplayEffect 적용
-> Health Attribute 감소

이렇게 하면 Attribute 변경, 복제, UI 갱신 같은 흐름과 자연스럽게 연결할 수 있다.

그래서 GameplayEffect는 단순한 버프나 디버프뿐만 아니라,
GAS에서 수치 변화를 처리하는 핵심 요소라고 볼 수 있다.


AttributeSet

AttributeSet은 캐릭터가 가진 수치 값을 모아두는 클래스이다.
예를 들어 다음과 같은 값들을 Attribute로 관리할 수 있다.

  • Health
  • MaxHealth
  • Mana
  • Stamina
  • AttackPower
  • Defense

AttributeSet은 단순히 수치를 저장하는 역할만 하는 것이 아니라,
GameplayEffect에 의해 값이 변경되었을 때 후처리를 할 수 있는 지점도 제공한다.

예를 들어 Health가 0 이하가 되었는지 확인하거나,
값이 변경되었을 때 UI 갱신 흐름으로 연결할 수 있다.

실습에서는 Health와 MaxHealth 같은 값을 AttributeSet에 두고,
GameplayEffect를 통해 Health를 변경하는 흐름으로 사용했다.


GameplayTag

GameplayTag는 GAS에서 상태나 의미를 표현하기 위한 태그이다.
문자열보다 안전하고, enum보다 유연하게 상태를 표현할 수 있다는 점이 특징이다.

GameplayTag는 점(.)을 이용해 계층 구조로 만들 수 있다.

Abilities.Attack.Primary
Abilities.Enemy.HitReact
Status.Death
Events.Enemy.HitReact

이런 태그를 사용하면 Ability, 상태, 입력, 이벤트를 클래스에 직접 의존하지 않고 구분할 수 있다.

예를 들어 공격 Ability를 실행할 때
특정 클래스를 직접 찾는 대신 Abilities.Attack.Primary 같은 태그로 실행할 Ability를 찾을 수 있다.

또 피격 이벤트를 전달할 때도
Events.Enemy.HitReact 같은 태그를 사용해 이벤트의 의미를 전달할 수 있다.

즉, GameplayTag는 GAS에서 요소들을 느슨하게 연결해주는 표식 역할을 한다.


GameplayCue

GameplayCue는 이펙트, 사운드, 카메라 흔들림 같은 연출을 처리하기 위한 요소이다.
데미지를 입었을 때 다음과 같은 연출이 필요할 수 있다.

  • 피격 파티클
  • 피격 사운드
  • 카메라 쉐이크
  • 피격 몽타주

물론 간단한 프로젝트라면 Ability 안에서 직접 이펙트를 재생할 수도 있다.
하지만 GAS에서는 GameplayCue를 사용해 게임플레이 로직과 연출을 분리할 수 있다.

GameplayCue는 Ability에서 직접 실행할 수도 있고,
GameplayEffect와 연결되어 효과가 적용될 때 실행되도록 사용할 수도 있다.

예를 들어 Ability는 “피격 이벤트가 발생했다”는 사실만 전달하고,
GameplayCue는 그에 맞는 파티클이나 사운드를 재생하도록 만들 수 있다.

이렇게 하면 데미지 처리와 연출 처리를 분리할 수 있어 구조가 더 깔끔해질 수 있다.


ASC는 어디에 둘까?

GAS를 공부하면서 가장 헷갈렸던 부분 중 하나는 AbilitySystemComponent를 어디에 둘 것인가였다.
ASC는 보통 캐릭터에 둘 수도 있고, PlayerState에 둘 수도 있다.

강의 실습에서는 플레이어의 ASC를 PlayerState에 두고,
실제 조작하는 캐릭터를 AvatarActor로 사용하는 구조를 다뤘다.

이때 개념적으로는 다음과 같이 볼 수 있다.

OwnerActor  : PlayerState
AvatarActor : PlayerCharacter

OwnerActor는 ASC를 소유하는 Actor이고,
AvatarActor는 실제 Ability가 적용되거나 표현되는 Actor이다.

PlayerState는 플레이어의 지속적인 정보를 담기 좋기 때문에,
캐릭터가 리스폰되더라도 ASC를 유지해야 하는 구조에서 사용할 수 있다.
다만 PlayerState에 ASC를 둘 경우 복제 타이밍이나 NetUpdateFrequency 같은 네트워크 설정도 함께 고려해야 한다.

반대로 적 캐릭터나 단순한 NPC처럼 리스폰 이후에도 유지할 필요가 크지 않은 경우에는
ASC를 캐릭터 자체에 두는 방식도 사용할 수 있다.

결국 ASC를 어디에 둘지는 게임 구조와 리스폰, 소유권, 네트워크 복제 방식을 함께 고려해서 결정해야 한다.


InitAbilityActorInfo

ASC를 사용하려면 InitAbilityActorInfo를 통해 OwnerActor와 AvatarActor 정보를 초기화해야 한다.
플레이어의 ASC가 PlayerState에 있고, Character를 AvatarActor로 사용하는 경우에는 초기화 타이밍이 중요하다.

서버에서는 보통 PossessedBy()에서 초기화할 수 있고,
클라이언트에서는 PlayerState가 복제된 뒤 OnRep_PlayerState()에서 초기화할 수 있다.

Server
-> PossessedBy()
-> InitAbilityActorInfo(PlayerState, Character)

Client
-> OnRep_PlayerState()
-> InitAbilityActorInfo(PlayerState, Character)

이렇게 서버와 클라이언트에서 각각 초기화하는 이유는
서버와 클라이언트가 PlayerState와 Character를 준비하는 타이밍이 다를 수 있기 때문이다.

즉, GAS를 사용할 때는 ASC를 만들기만 하는 것이 아니라,
ASC가 어떤 Actor를 소유자로 보고 어떤 Actor에 적용될 것인지 초기화해줘야 한다.


GameplayEffect Replication Mode 간단 정리

GAS를 멀티플레이에서 사용할 때는 GameplayEffect 정보를 얼마나 자세히 복제할지도 설정할 수 있다.
이를 EGameplayEffectReplicationMode라고 한다.

대표적으로 다음과 같은 모드가 있다.

모드 설명
Minimal GameplayEffect 정보를 최소한만 복제
Mixed 소유자와 Autonomous Proxy에는 자세히, Simulated Proxy에는 최소 정보만 복제
Full 모든 클라이언트에게 GameplayEffect 정보를 자세히 복제

Minimal은 네트워크 비용이 적기 때문에 몬스터나 NPC에 사용할 수 있다.

Mixed는 플레이어 캐릭터에 자주 사용되며,
소유한 클라이언트에게는 필요한 정보를 자세히 주고
다른 클라이언트에게는 최소한의 정보만 전달하는 방식이다.

Full은 모든 클라이언트에게 자세한 GameplayEffect 정보를 복제하므로
학습이나 디버깅에는 편하지만, 비용이 더 클 수 있다.

처음 실습할 때는 Full이 이해하기 쉬울 수 있지만,
실제 프로젝트에서는 네트워크 비용을 고려해서 적절한 모드를 선택해야 한다.


GAS를 볼 때 생각할 것

GAS는 요소가 많아서 처음에는 구조가 복잡하게 느껴졌다.

하지만 다음 질문들을 기준으로 보면 조금 더 정리하기 쉬웠다.

ASC는 어디에 둘 것인가?
OwnerActor와 AvatarActor는 무엇인가?
AttributeSet은 어떤 수치를 가질 것인가?
Ability는 어떤 행동 단위로 나눌 것인가?
입력은 어떤 GameplayTag와 연결할 것인가?
상태는 어떤 GameplayTag로 표현할 것인가?
연출은 GameplayCue로 분리할 것인가?

이 질문들은 GAS 구조를 설계할 때 계속 확인해야 할 기준이 될 수 있다.

이번 글에서는 Cost와 Cooldown은 자세히 다루지 않았지만,
나중에 Ability 실행 조건과 함께 따로 정리해볼 예정이다.


정리

GAS는 캐릭터의 능력, 수치, 상태, 효과, 연출을 나누어 관리할 수 있게 해주는 시스템이다.

핵심 구성 요소를 정리하면 다음과 같다.

구성 요소 역할
AbilitySystemComponent GAS의 중심 컴포넌트
GameplayAbility 공격, 회피, 스킬 같은 행동
GameplayEffect Attribute 변경, 버프, 디버프, 쿨타임 처리
AttributeSet Health, Mana, Stamina 같은 수치 저장
GameplayTag 상태, 입력, 이벤트, Ability를 구분하는 표식
GameplayCue 이펙트, 사운드 같은 연출 처리

이번 실습을 통해 GAS는 단순히 스킬 시스템만을 위한 기능이 아니라,
캐릭터의 행동과 상태 변화를 구조적으로 관리하기 위한 시스템이라는 느낌을 받았다.

아직 모든 내용을 완전히 이해한 것은 아니지만, 각 요소가 어떤 역할을 하는지 먼저 구분해두면
이후 GameplayAbility, GameplayEffect, AttributeSet 흐름을 이해하는 데 도움이 될 것 같다.


마무리

이번 글에서는 GAS의 기본 구성 요소를 간단히 정리했다.

처음에는 용어가 많아서 어렵게 느껴졌지만,
각 요소가 담당하는 역할을 나누어 보니 조금씩 구조가 보이기 시작했다.

특히 ASC가 중심에서 Ability, Effect, Attribute, Tag를 관리하고,
GameplayAbility는 행동을 담당하고, GameplayEffect는 수치나 상태 변화를 처리한다는 흐름이 중요해 보였다.

아직은 강의 실습을 통해 익힌 단계라 실제 프로젝트에 바로 적용하려면 더 많은 고민이 필요할 것 같다.

다음 글에서는 GameplayAbility와 GameplayEvent를 중심으로,
Ability가 어떻게 실행되고 이벤트 기반으로 다른 Ability와 연결되는지 정리해보려고 한다.