GAS란?
- GAS( Game Ability System )은 언리얼 엔진에서 캐릭터의 능력, 상태, 효과, 수치 변화를 체계적으로 관리하기 위한 프레임워크
이다.
일반적으로 RPG, 액션 게임, 스킬 기반 전투 시스템처럼 캐릭터가 다양한 능력을 사용하고, 버프/디버프를 받으며,
HP나 공격력 같은 스탯이 계속 변화하는 게임에서 자주 사용된다.

GAS의 구성요소 정리
- ASC( Ability System Component )
- Tag ( Game Play Tag )
- GA ( Game Play Ability )
- GE ( Game Play Effect )
- Attribute
GAS 전체 흐름
- ASC 컴포넌트 생성 ( CreateDefaultSubObject ).
- OwnerActor / AvatarActor 초기화 ( InitAbilityActorInfo 설정 )
- Attribute Set 등록 ( 스탯 (HP, MP 등 ) 정의 )
- Gameplay Effect 적용 ( 스탯 초기값 설정 )
- Gameplay Ability 등록 ( GiveAbility 함수를 통해 등록 )
- Ability 발동 ( TryActivateAbility )
Ability System Component ( ASC )
- Ability System Component 는 액터 컴포넌트의 일종으로 모든 시스템의 상호작용을 책임지는 역할을 맡습니다.
따라서 GameplayAbilities, Attribute, GameplayEffect 등을 사용하려는 액터는 반드시 ASC가 부착되어야 한다.
ASC을 부착하기 위해선 다음과 같은 과정이 필요하다.
#include "AbilitySystemComponent.h"
#include "Abilities/GameplayAbility.h"
UPROPERTY(EditAnywhere, Category = GAS)
TObjectPtr<class UAbilitySystemComponent> ASC; // 어빌리티 시스템 컴포넌트

ASC = CreateDefaultSubObject<UAbilitySystemComponent>(TEXT("ASC")); // Actor의 컴포넌트에 넣어주기
ASC->InitAbilityActorInfo(this,this) // OwnerActor와 AvatarActor 설정
OwnerActor 와 AvatarActor란?
- OwnerActor : ASC를 논리적으로 소유한 주체 ( 해당 주체가 죽어도 유지되며, 레벨 및 스텐 보존 )
- AvatarActor : Character ( 죽으면 바뀌는 물체 , 실제로 데이터를 처리하지 않지만 비주얼만 수행해 주는 엑터 )
여기까지가 ASC를 부착하고 , ASC에게 자신이 누구의 것인지 알려준 과정 2번 까지이다.
현재 예제 프로젝트에서는 Player의 스탯 값과 스킬 어빌리티 등이 존재하지 않고 간단한 회전 Ability만 제공해서 확인할 예정이므로 3번~5번 작업은 건너뛰고 계속 진행해 보겠습니다.
// GAS를 사용할때 ( TAG 없이 )
FGameplayAbilitySpec* RotateGASpec = ASC->FindAbilitySpecFromClass(UABGA_Rotate::StaticClass());
if(RotateGASpec == NULL)
{
ABGAS_LOG(LogABGAS, Error, TEXT("No Rotate Spec Found!"));
return;
}
if(!RotateGASpec->IsActive())
{
ASC->TryActivateAbility(RotateGASpec->Handle);
}
else
{
ASC->CancelAbilityHandle(RotateGASpec->Handle);
}
RotateGASpec는 오브젝트가 회전하도록 하는 Gameplay Ability입니다.
해당 Ability를 발동시키려면 ASC의 TryActivateAbility()를 호출하며, 내부 조건 검증을 통과하면 RotateGASpec의 ActivateAbility()가 최종적으로 호출됩니다.
이때 어떤 Ability를 발동시킬지 특정하기 위해 RotateGASpec->Handle을 사용합니다.
Handle을 사용하는 이유는 같은 Ability 클래스라도 ASC에 여러번 등록될 수 있기 때문에, 클래스 명만으로는 어떤 인스터인지 구분할 수 없기 때문입니다. Handle은 각 Ability 인스턴스에 부여된 고유 식별자로, 이를 통해 원하는 Ability를 정확히 지정하여 발동 및 취소할 수 있습니다.
다음과 같은 상황을 고려해보면 알 수 있습니다.
ASC->GiveAbility(FGameplayAbilitySpec(UABGA_Rotate::StaticClass())); // Handle: 101
ASC->GiveAbility(FGameplayAbilitySpec(UABGA_Rotate::StaticClass())); // Handle: 102
다음과 같이 GiveAbility를 다음과 같이 호출 및 취소 할 수 있습니다.
// GiveAbility가 Handle을 반환함
FGameplayAbilitySpecHandle RotateHandle = ASC->GiveAbility(
FGameplayAbilitySpec(UABGA_Rotate::StaticClass())
);
// 나중에 이 Handle로 발동/취소
ASC->TryActivateAbility(RotateHandle);
ASC->CancelAbilityHandle(RotateHandle);
Game Tag를 이용하여 GA( Game Ability ) 호출 해보기
우선 Game Tag를 설정하기 위해서는 다음과 같은 과정이 필요로 합니다.


Actor.Action.Rotate로 "." 단위로 해당 기능을 분류할 수 있다.
해당 Game Play Tag를 다 설정해주었다면, cpp에서 해당 Tag를 활용하기 위해 해당 Tag 매크로 헤더 파일을 만들어 다뤄보자.

그다음 현재 StartAbilities가 선언되어 있지 않으므로 unreal editor에서 직접 설정해주자

void AABGASFountain::PostInitializeComponents()
{
Super::PostInitializeComponents();
RotatingMovement->bAutoActivate = false;
RotatingMovement->Deactivate();
// OwnerActor = 실제 ASC를 구동하고 데이터를 관리하는 어떤 실제 작업이 일어나고 있는 엑터 정보 ( 죽어도 유지됨, 레벨/스텟 보존)
// AvatarActor = 실제로 데이터를 처리하지 않지만 비주얼만 수행해 주는 엑터만 지정하는 것 ( 죽으면 바뀜, 새 캐릭터로 교체 )
ASC->InitAbilityActorInfo(this, this); // ASC 입장에서 " 나를 소유한 게 누구고, 실제로 몸을 가진 게 누군지"를 알아야 어빌리티 발동 및 이펙트 적용 및 애니메이션 재생등을함.
for (const auto& StartAbility : StartAbilities)
{
FGameplayAbilitySpec StartSpec(StartAbility);
ASC->GiveAbility(StartSpec);
}
// Tag가 없을때
//FGameplayAbilitySpec RotateSkillSpec(UABGA_Rotate::StaticClass());
//ASC->GiveAbility(RotateSkillSpec);
}
void AABGASFountain::BeginPlay()
{
Super::BeginPlay();
GetWorld()->GetTimerManager().SetTimer(ActionTimer, this, &AABGASFountain::TimerAction, ActionPeriod, true, 0.0f);
}
void AABGASFountain::TimerAction()
{
ABGAS_LOG(LogABGAS, Log, TEXT("Begin"));
FGameplayTagContainer TargetTag(ABTAG_ACTOR_ROTATE); // 발동 시킬 태그
// 어빌리티가 발동이 되면은 ISROTATING 태그가 심어짐
if(!ASC->HasMatchingGameplayTag(ABTAG_ACTOR_ISROTATING))
{
ASC->TryActivateAbilitiesByTag(TargetTag);
}
else
{
ASC->CancelAbilities(&TargetTag);
}
}
여기까지 GAS의 간단한 활용방법 및 Gameplay Tag를 통한 활용방법에 대해 알아보았다.
'Unreal Project > GAS' 카테고리의 다른 글
| GAS을 활용한 캐릭터의 입력 처리 구현 (0) | 2026.05.02 |
|---|