07
07

https://github.com/jiwonchoidd/UE5_GasTutorial

 

GAS는 게임플레이 어빌리티 시스템(Gameplay Ability System)의 약자로, 주로 언리얼 엔진(Unreal Engine)에서 사용되는 강력한 프레임워크입니다

GAS의 핵심 구성 요소 3가지

  1. 어트리뷰트 (Attributes)
    • 캐릭터의 능력치(스탯)입니다.
    • 예: 체력(Health), 마나(Mana), 공격력(AttackPower), 이동속도(MoveSpeed) 등.
    • 이 값들은 다른 요소들에 의해 실시간으로 변경됩니다.
  2. 어빌리티 (Abilities)
    • 캐릭터가 사용할 수 있는 액션이나 스킬입니다.
    • 예: 파이어볼 발사, 칼 휘두르기, 회복 물약 마시기.
    • 어빌리티는 발동 조건(마나 소모 등), 쿨타임, 실행 로직 등을 가집니다.
  3. 게임플레이 이펙트 (Gameplay Effects)
    • 어트리뷰트를 변경하는 역할을 합니다. 즉, 버프와 디버프를 구현합니다.
    • 예:
      • 힘 증가 버프: 30초 동안 공격력 어트리뷰트를 +10 증가시킴.
      • 독 디버프: 5초 동안 매초 체력 어트리뷰트를 -5 감소시킴.
      • 힐: 체력 어트리뷰트를 즉시 +100 회복시킴.

 

https://youtu.be/Fb5y4PWtud8?si=UgFUTJs7BOo2q-OS

 

1. 예제 프로젝트 구성

	// add build.cs
	PublicDependencyModuleNames.AddRange(new string[] {
			/...
			"GameplayAbilities",
			"GameplayTags",
			"GameplayTasks",
			.../
		});
        
	// add .uproject
			"Plugins": [
		/...
		{
			"Name": "GameplayAbilities",
			"Enabled": true
		}

Ability System을 사용하기 위해 플러그인 추가를 합니다.

 

2. Game Ability 생성

UGameAbility를 상속받는 클래스로 Ability 객체 생성

void UGWAbility_Jump::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
	if (!ActorInfo->AvatarActor.IsValid())
		return;

	ACharacter* Character = Cast<ACharacter>(ActorInfo->AvatarActor.Get());
	if (nullptr == Character)
		return;

#if WITH_EDITOR
	GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, TEXT("UGWAbility_Jump::ActivateAbility"));
#endif
	Character->Jump();

	EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
}

해당 함수를 오버라이딩해서 Jump 능력을 사용할 수 있도록 구성합니다.

이 클래스를 상속받는 BP 에셋을 생성하고 + 버튼을 눌러서 Ability 태그를 지정합니다.

아래는 어빌리티 관련된 주요 함수들

엔진 코드
	//	The important functions:
	//	
	//		CanActivateAbility()	- const function to see if ability is activatable. Callable by UI etc
	//
	//		TryActivateAbility()	- Attempts to activate the ability. Calls CanActivateAbility(). Input events can call this directly.
	//								- Also handles instancing-per-execution logic and replication/prediction calls.
	//		
	//		CallActivateAbility()	- Protected, non virtual function. Does some boilerplate 'pre activate' stuff, then calls ActivateAbility()
	//
	//		ActivateAbility()		- What the abilities *does*. This is what child classes want to override.
	//	
	//		CommitAbility()			- Commits reources/cooldowns etc. ActivateAbility() must call this!
	//		
	//		CancelAbility()			- Interrupts the ability (from an outside source).
	//
	//		EndAbility()			- The ability has ended. This is intended to be called by the ability to end itself.
	//	
	// ----------------------------------------------------------------------------------------------------------------

 

3. 캐릭터 GameAbilitySystem 구현

마찬가지로 UAbilitySystemComponent를 상속받는 클래스를 하나 생성해주고 해당 캐릭터 컴포넌트를 사용할 캐릭터 생성자에 추가합니다.

// Create a AbilitySystem
AbilitySystem = CreateDefaultSubobject<UGWAbilitySystemComponent>(TEXT("AbilitySystem"));

캐릭터에는 능력 관련된 입력 바인딩 정보, 능력 부여하는 코드 작성하면 됩니다.

3-1. 입력 바인딩 정보

Confirm 어빌리티의 타켓팅을 확정하고 최종 실행하라는 신호

Cancel 진행중인 어빌리티를 취소하라는 신호.

SetupPlayerInputCompoent 실행 시 관련되어 정의한 Enum Path 등 구조체를 넘겨 입력 바인딩을 등록함

void AGasTutorialCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	// Set up action bindings
	if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent)) {
		...
		if(AbilitySystem)
		{
			// 5.1 Enum 네임 -> Enum 경로로 변경됨
			FGameplayAbilityInputBinds InputBind = FGameplayAbilityInputBinds(
				TEXT("Confirm"),
				TEXT("Cancel"),
				FTopLevelAssetPath(StaticEnum<EGasAbilityInputId>()->GetPathName()),
				static_cast<int32>(EGasAbilityInputId::Confirm),
				static_cast<int32>(EGasAbilityInputId::Cancel));

			AbilitySystem->BindAbilityActivationToInputComponent(PlayerInputComponent, InputBind);
		}
	}

3-2. 캐릭터 능력 등록

// BP 에서 지정할 수 있게 능력 TSubClassOf로 구현
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category= "GWAbility")
TArray<TSubclassOf<class UGameplayAbility>> DefaultAbilities;


void AGasTutorialCharacter::BeginPlay()
{
	Super::BeginPlay();

	if (AbilitySystem)
	{
		for (TSubclassOf<UGameplayAbility>& Ability : DefaultAbilities)
		{
			if (!Ability)
				continue;

			AbilitySystem->GiveAbility(
				FGameplayAbilitySpec(Ability, 1, static_cast<int32>(EGasAbilityInputId::Confirm), this));
		}
	}
}

캐릭터 BP 에서 아까 만든 Jump 어빌리티를 등록해놓고 캐릭터의 BeginPlay 시점에 능력을 부여합니다.

 

4. 능력 사용 

간단히 블루프린트로 AnyKey 입력 시 능력 사용하도록 구현합니다.

관련되어서 3개 함수가 보였네요. 각각 태그, 클래스, 핸들로 능력 사용하는걸로 보입니다.

태그로 F 버튼 입력 시 호출하도록 구현했습니다.

점프하고 있는 모습

 

 

트리거나 쿨타임 기능도 있으니 추후 사용해볼 예정

 

COMMENT