[UE GAS] 어빌리티시스템 컴포넌트 AbilitySystemComponent, 게임플레이 태그 Gameplay Tag
게임플레이 어빌리티 시스템(GAS) 기본 설정 방법의 학습
- 어빌리티 시스템 컴포넌트의 생성과 초기화
- 게임플레이 어빌리티의 제작과 활용
- 게임플레이 태그의 활용
다양한 구현 방법이 가진 장단점의 이해
목차
ASC와 Gameplay Tag의 활용
AbilitySystemComponent와 Gameplay Tag의 사용
분수대 액터의 기획
3초 마다 회전과 정지를 무한 반복하면서 동작하는 분수대
회전 기능은 RotatingMovementComponent
이를 어떻게 구현할 것인가?
- 전통적인 방법: 액터에 해당 기능을 구현
- GAS를 사용한 방법: 게임플레이 어빌리티 시스템으로 구현
- GAS + Gameplay Tag: 게임플레이 어빌리티 시스템에 게임플레이 태그를 부여해 구현
#1 전통적인 방법: 액터에 해당 기능을 구현
ABGASFountain.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Prop/ABFountain.h"
#include "ABGASFountain.generated.h"
UCLASS()
class ARENABATTLEGAS_API AABGASFountain : public AABFountain, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
AABGASFountain();
protected:
virtual void PostInitializeComponents() override;
virtual void BeginPlay() override;
virtual void TimerAction();
protected:
UPROPERTY(VisibleAnywhere, Category=Movement)
TObjectPtr<class URotatingMovementComponent> RotatingMovement;
UPROPERTY(EditAnywhere, Category=Timer)
float ActionPeriod;
FTimerHandle ActionTimer;
};
ABGASFountain.cpp
더보기
#include "Prop/ABGASFountain.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "ArenaBattleGAS.h"
AABGASFountain::AABGASFountain()
{
RotatingMovement = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotateMovement"));
ActionPeriod = 3.0f;
}
UAbilitySystemComponent* AABGASFountain::GetAbilitySystemComponent() const
{
return ASC;
}
void AABGASFountain::PostInitializeComponents()
{
Super::PostInitializeComponents();
RotatingMovement->bAutoActivate = false;
RotatingMovement->Deactivate();
}
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"));
if (!RotatingMovement->IsActive())
{
RotatingMovement->Activate(true);
}
else
{
RotatingMovement->Deactivate();
}
}
실행화면
Ability System Component(ASC) & Gameplay Ability(GA)
어빌리티 시스템 컴포넌트 Ability System Component(ASC)
Ability System Component (ASC)
- 게임플레이 어빌리티 시스템을 관리하는 핵심 컴포넌트
- 게임플레이 어빌리티 및 다양한 작업을 관리하고 처리하는 중앙 처리 장치
- 액터에 단 하나만 부착할 수 있음
- 액터는 부착된 AbilitySystemComponent(ASC)를 통해 게임플레이 어빌리티를 발동시킬 수 있음
- AbilitySystemComponent(ASC)를 부착한 액터 사이에 GAS 시스템의 상호 작용이 가능해짐
게임플레이 어빌리티 Gameplay Ability
Gameplay Ability (GA)
- AbilitySystemComponent(ASC)에 등록되어 발동시킬 수 있는 액션 명령
- 공격, 마법, 특수 공격 등등
- 간단한 액션 뿐만 아니라 상황에 따른 복잡한 액션 수행 가능
- GA의 발동 과정
- ASC에 어빌리티를 등록: ASC의 GiveAbility 함수에 발동할 ' GA의 타입 '을 전달
- 발동할 GA 타입 정보를 게임플레이 어빌리티 스펙(GameplayAbilitySpec)이라고 함
- ASC에게 어빌리티를 발동하라고 명령: ASC의 TryActivateAbility 함수에 발동할 ' GA의 타입 '을 전달
- ASC에 등록된 타입이면 GA의 인스턴스가 생성됨
- 발동된 GA에는 발동한 액터와 실행 정보가 기록됨
- SpecHandle: 발동한 어빌리티에 대한 핸들
- ActorInfo: 어빌리티의 소유자와 아바타 정보
- ActivationInfo: 발동 방식에 대한 정보
- ASC에 어빌리티를 등록: ASC의 GiveAbility 함수에 발동할 ' GA의 타입 '을 전달
- GA의 주요 함수
GA의 주요 함수 | |
CanActivateAbility | 어빌리티가 발동될 수 있는지 파악 |
ActivateAbility | 어빌리티가 발동될 때 호출 |
CancelAbility | 어빌리티가 취소될 때 호출 |
EndAbility | 스스로 어빌리티를 마무리할 때 호출 |
#2 GAS를 사용한 방법: 게임플레이 어빌리티 시스템으로 구현
ABGASFountain.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Prop/ABFountain.h"
#include "AbilitySystemInterface.h"
#include "ABGASFountain.generated.h"
UCLASS()
class ARENABATTLEGAS_API AABGASFountain : public AABFountain, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
AABGASFountain();
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
protected:
virtual void PostInitializeComponents() override;
virtual void BeginPlay() override;
virtual void TimerAction();
protected:
UPROPERTY(VisibleAnywhere, Category=Movement)
TObjectPtr<class URotatingMovementComponent> RotatingMovement;
UPROPERTY(EditAnywhere, Category=Timer)
float ActionPeriod;
UPROPERTY(EditAnywhere, Category=GAS)
TObjectPtr<class UAbilitySystemComponent> ASC;
FTimerHandle ActionTimer;
};
함수 추가
- virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
변수 추가
- UPROPERTY(EditAnywhere, Category=GAS)
TObjectPtr<class UAbilitySystemComponent> ASC;
ABGASFountain.cpp
더보기
#include "Prop/ABGASFountain.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "ArenaBattleGAS.h"
#include "AbilitySystemComponent.h"
#include "GameplayAbilitySpec.h"
#include "GA/ABGA_Rotate.h"
AABGASFountain::AABGASFountain()
{
ASC = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("ASC"));
RotatingMovement = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotateMovement"));
ActionPeriod = 3.0f;
}
UAbilitySystemComponent* AABGASFountain::GetAbilitySystemComponent() const
{
return ASC;
}
void AABGASFountain::PostInitializeComponents()
{
Super::PostInitializeComponents();
RotatingMovement->bAutoActivate = false;
RotatingMovement->Deactivate();
ASC->InitAbilityActorInfo(this, this); // ASC 초기화
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"));
FGameplayAbilitySpec* RotateGASpec = ASC->FindAbilitySpecFromClass(UABGA_Rotate::StaticClass());
if (!RotateGASpec)
{
ABGAS_LOG(LogABGAS, Error, TEXT("No Rotate Spec Found!"));
return;
}
if (!RotateGASpec->IsActive()) // 활성화되어 있지 않다면
{
ASC->TryActivateAbility(RotateGASpec->Handle); // Handle를 지정하여활성화
}
else
{
ASC->CancelAbilityHandle(RotateGASpec->Handle); // 비활성화하여 취소
}
}
헤더추가
- #include "AbilitySystemComponent.h"
- #include "GameplayAbilitySpec.h"
- #include "GA/ABGA_Rotate.h"
함수 구현 변경
- void AABGASFountain::PostInitializeComponents()
- ASC->InitAbilityActorInfo(this, this);
FGameplayAbilitySpec RotateSkillSpec(UABGA_Rotate::StaticClass());
ASC->GiveAbility(RotateSkillSpec);
- ASC->InitAbilityActorInfo(this, this);
- void AABGASFountain::TimerAction()
새 C++ 클래스 - GameplayAbility - ABGA_Rotate 생성
ABGA_Rotate.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Abilities/GameplayAbility.h"
#include "ABGA_Rotate.generated.h"
UCLASS()
class ARENABATTLEGAS_API UABGA_Rotate : public UGameplayAbility
{
GENERATED_BODY()
public:
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility) override;
};
ABGA_Rotate.cpp
더보기
#include "GA/ABGA_Rotate.h"
#include "GameFramework/RotatingMovementComponent.h"
void UABGA_Rotate::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
AActor* AvatarActor = ActorInfo->AvatarActor.Get();
if (AvatarActor)
{
URotatingMovementComponent* RotatingMovement = Cast<URotatingMovementComponent>(AvatarActor->GetComponentByClass(URotatingMovementComponent::StaticClass()));
if (RotatingMovement)
{
RotatingMovement->Activate(true);
}
}
}
void UABGA_Rotate::CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility)
{
Super::CancelAbility(Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility);
AActor* AvatarActor = ActorInfo->AvatarActor.Get();
if (AvatarActor)
{
URotatingMovementComponent* RotatingMovement = Cast<URotatingMovementComponent>(AvatarActor->GetComponentByClass(URotatingMovementComponent::StaticClass()));
if (RotatingMovement)
{
RotatingMovement->Deactivate();
}
}
}
실행화면
Gameplay Tag
게임플레이 태그 Gameplay Tag
Gameplay Tag
- 게임플레이 어빌리티 시스템과 독립적으로 사용 능
- FName으로 관리되는 경량의 표식 데이터
- 액터나 컴포넌트에 지정했던 태그와 다른 데이터
- 프로젝트 설정에서 별도로 게임플레이 태그를 생성하고 관리할 수 있음
- 결과는 DefaultGameplayTags.ini 파일에 저장됨
- 계층 구조로 구성되어 있어 체계적인 관리 가능
- Actor.Action.Rotate: 행동에 대한 태그
- Actor.State.IsRotating: 상태에 대한 태그
- 게임플레이 태그들의 저장소: GampleyTagContainer
- 계층 구조를 지원하는 검색 기능 제공
HasTagExact | 컨테이너에 A.1태그가 있는 상황에서 A로 찾으면 false |
HasAny | 컨테이너에 A.1태그가 있는 상황에서 A와 B로 찾으면 true |
HasAnyExact | 컨테이너에 A.1태그가 있는 상황에서 A와 B로 찾으면 false |
HasAll | 컨테이너에 A.1태그와 B.1태그가 있는 상황에서 A와 B로 찾으면 true |
HasAllExact | 컨테이너에 A.1태그와 B.1태그가 있는 상황에서 A와 B로 찾으면 false |
게임플레이 어빌리티(Gameplay Ability)와 게임플레이 태그(Gameplay Tag)
게임플레이 어빌리티(Gameplay Ability)에 부착한 태그
- 어빌리티에 지정한 태그 ( AbiltiyTags 태그 컨테이너 )
게임플레이 어빌리티(Gameplay Ability)에 대해 다양한 실행 조건의 설정
CancelAbilitiesWithTag 태그 컨테이너 | Tag로 어빌리티 취소 |
BlockAbilitiesWithTag 태그 컨테이너 | Tag로 어빌리티 차단 |
ActivationOwnedTags 태그 컨테이너 | 어빌리티 실행시 태그 설정 |
ActivationRequiredTags 태그 컨테이너 | Tag가 있어야만 어빌리티 실행 |
ActivationBlockedTags 태그 컨테이너 | Tag가 있으면 어빌리티 실행 차단 |
SourceRequiredTags 태그 컨테이너 | 시전자가 Tag가 있어야 어빌리티 실행 |
SourceBlockedTags 태그 컨테이너 | 시전자에 Tag가 있으면 어빌리티 차단 |
TargetRequiredTags 태그 컨테이너 | 시전 대상에 Tag가 있어야 어빌리티 실행 |
TargetBlockedTags 태그 컨테이너 | 시전 대상에 태그가 있으면 어빌리티 차단 |
블루프린트와 조합하여 특정 게임플레이 어빌리티에 대한 의존성을 없애고
게임플레이 태그를 중심으로 게임 로직을 전개 가능
#3 GAS + Gameplay Tag: 게임플레이 어빌리티 시스템에 게임플레이 태그를 부여해 구현
프로젝트 세팅에 Gameplay Tag 추가
ABGASFountain.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Prop/ABFountain.h"
#include "AbilitySystemInterface.h"
#include "ABGASFountain.generated.h"
UCLASS()
class ARENABATTLEGAS_API AABGASFountain : public AABFountain, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
AABGASFountain();
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
protected:
virtual void PostInitializeComponents() override;
virtual void BeginPlay() override;
virtual void TimerAction();
protected:
UPROPERTY(VisibleAnywhere, Category=Movement)
TObjectPtr<class URotatingMovementComponent> RotatingMovement;
UPROPERTY(EditAnywhere, Category=Timer)
float ActionPeriod;
UPROPERTY(EditAnywhere, Category=GAS)
TObjectPtr<class UAbilitySystemComponent> ASC;
UPROPERTY(EditAnywhere, Category=GAS)
TArray<TSubclassOf<class UGameplayAbility>> StartAbilities;
FTimerHandle ActionTimer;
};
ABGASFountain.cpp
더보기
#include "Prop/ABGASFountain.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "ArenaBattleGAS.h"
#include "AbilitySystemComponent.h"
#include "GameplayAbilitySpec.h"
#include "Tag/ABGameplayTag.h"
#include "Abilities/GameplayAbility.h"
//#include "GA/ABGA_Rotate.h"
AABGASFountain::AABGASFountain()
{
ASC = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("ASC"));
RotatingMovement = CreateDefaultSubobject<URotatingMovementComponent>(TEXT("RotateMovement"));
ActionPeriod = 3.0f;
}
UAbilitySystemComponent* AABGASFountain::GetAbilitySystemComponent() const
{
return ASC;
}
void AABGASFountain::PostInitializeComponents()
{
Super::PostInitializeComponents();
RotatingMovement->bAutoActivate = false;
RotatingMovement->Deactivate();
ASC->InitAbilityActorInfo(this, this);
for (const auto& StartAbility : StartAbilities)
{
FGameplayAbilitySpec StartSpec(StartAbility);
ASC->GiveAbility(StartSpec);
}
}
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);
if(!ASC->HasMatchingGameplayTag(ABTAG_ACTOR_ISROTATING))
{
ASC->TryActivateAbilitiesByTag(TargetTag);
}
else
{
ASC->CancelAbilities(&TargetTag);
}
}
ABGA_Rotate.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Abilities/GameplayAbility.h"
#include "ABGA_Rotate.generated.h"
UCLASS()
class ARENABATTLEGAS_API UABGA_Rotate : public UGameplayAbility
{
GENERATED_BODY()
public:
UABGA_Rotate();
public:
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility) override;
};
생성자 추가
- UABGA_Rotate();
ABGA_Rotate.cpp
더보기
#include "GA/ABGA_Rotate.h"
#include "GameFramework/RotatingMovementComponent.h"
#include "Tag/ABGameplayTag.h"
UABGA_Rotate::UABGA_Rotate()
{
AbilityTags.AddTag(ABTAG_ACTOR_ROTATE);
ActivationOwnedTags.AddTag(ABTAG_ACTOR_ISROTATING);
}
void UABGA_Rotate::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
AActor* AvatarActor = ActorInfo->AvatarActor.Get();
if (AvatarActor)
{
URotatingMovementComponent* RotatingMovement = Cast<URotatingMovementComponent>(AvatarActor->GetComponentByClass(URotatingMovementComponent::StaticClass()));
if (RotatingMovement)
{
RotatingMovement->Activate(true);
}
}
}
void UABGA_Rotate::CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility)
{
Super::CancelAbility(Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility);
AActor* AvatarActor = ActorInfo->AvatarActor.Get();
if (AvatarActor)
{
URotatingMovementComponent* RotatingMovement = Cast<URotatingMovementComponent>(AvatarActor->GetComponentByClass(URotatingMovementComponent::StaticClass()));
if (RotatingMovement)
{
RotatingMovement->Deactivate();
}
}
}
헤더 추가
- #include "Tag/ABGameplayTag.h"
생성자 정의
- UABGA_Rotate::UABGA_Rotate()
실행화면
'⭐ Unreal Engine > UE Game Ability System(GAS)' 카테고리의 다른 글
[UE GAS] 캐릭터 어트리뷰트 설정 (0) | 2024.03.07 |
---|---|
[UE GAS] 공격 판정 시스템의 구현 (0) | 2024.03.06 |
[UE GAS] 캐릭터의 콤보 공격의 구현 Implementing Combo Action, 상태를가지는 점프 어빌리티의 구현하기 (0) | 2024.03.05 |
[UE GAS] 캐릭터 입력처리 (0) | 2024.03.05 |
[UE GAS] 어빌리티 시스템 (Game Ability System) (0) | 2024.03.03 |
댓글
이 글 공유하기
다른 글
-
[UE GAS] 공격 판정 시스템의 구현
[UE GAS] 공격 판정 시스템의 구현
2024.03.06 -
[UE GAS] 캐릭터의 콤보 공격의 구현 Implementing Combo Action, 상태를가지는 점프 어빌리티의 구현하기
[UE GAS] 캐릭터의 콤보 공격의 구현 Implementing Combo Action, 상태를가지는 점프 어빌리티의 구현하기
2024.03.05 -
[UE GAS] 캐릭터 입력처리
[UE GAS] 캐릭터 입력처리
2024.03.05 -
[UE GAS] 어빌리티 시스템 (Game Ability System)
[UE GAS] 어빌리티 시스템 (Game Ability System)
2024.03.03