게임플레이 이펙트(Gameplay Effect)는 게임플레이 어빌리티 시스템에서 어트리뷰트를 변경하는 방식이다.
게임플레이 이펙트를 사용하면 Attribute에 대해 다음과 같은 작업을 수행할 수 있다.
즉각적인 Attribute의 변경 (데미지, 치유 Ability)
지속적인 버프/디버프
영구적인 패시브 Ability
GameplayEffect는 다양한 방법으로 적용할 수 있다. 그 중 일반적인 방법은 다음과 같다.
Gameplay Ability를 통한 함수 호출
Ability System Component를 통한 호출

우선 간단하게 블루프린트로 Gameplay Effect를 생성하고 Attribute의 변경을 해보자.
Gameplay Effect 클래스를 부모로 삼는 GE_Damage를 생성하고, 아래와 같이 세팅해주자.

사용법은 간단하다.
정의에서 설명한대로 Attribute를 얼마만큼 적용할 지 설정하는 부분이다.
Instant : 즉각적으로 변경, 한프레임 내 실행
Duration : 지속시간만큼 실행
Infinite : 실행되고 나면 제거되기 전까지 실행
Gameplay Effect의 용도를 설정할 수 있는 부분이다. 여기서 다양한 조건을 설정하여 Gameplay Effect를 실행할 지 말지 결정할 수 있다.
Attribute를 어떤 방식으로 변경할 것인지에 대한 부분이다.
기본적인 Attribute 변경부터 데이터 테이블 이용, 커스텀 모디파이어 클래스 이용 등 다양한 방식과 조건을 설정하여 Attribute를 세밀하게 제어할 수 있다.

생성된 Gameplay Effect는 Ability 내부에서 Owner 혹은 Target에게 적용할 수 있으며, 혹은 Ability의 발동 비용이나 쿨타임도 적용 가능하다.
이제 우리는 Gameplay Ability를 통해 Gameplay Effect를 발동시켜 Attribute를 자유롭게 수정할 수 있다.
이를 응용해서 플레이어의 체력 Attribute를 생성해보자.
// GAS_AttributeSet.h
// Attribute 변경 이벤트를 위한 Delegate 정의
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FAttributeChangedEvent, float, OldValue, float, NewValue);
...
UCLASS()
class GASTEMPLATE_API UGAS_AttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;
virtual void PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue) override;]
...
// Delegate for attribute changes
UPROPERTY(BlueprintAssignable)
FAttributeChangedEvent OnHealthChanged;
// GAS_AttributeSet.cpp
#include "GAS/Attributes/GAS_AttributeSet.h"
void UGAS_AttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{
// 여기서 속성(Attribute)의 값을 제한하거나 조정할 수 있습니다.
}
void UGAS_AttributeSet::PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue)
{
// 속성(Attribute)의 값이 변경된 후에 추가적인 작업을 수행할 수 있습니다.
Super::PostAttributeChange(Attribute, OldValue, NewValue);
// Health 속성이 변경되었을 때 OnStaminaChanged 이벤트를 호출합니다.
if (Attribute == GetHealthAttribute())
{
OnHealthChanged.Broadcast(OldValue, NewValue);
}
}
여기서는 단순하게 Health Attribute 변경이 감지되면 이를 UI에서 이벤트로 발동하기 위해 Delegate로 묶어준다.
우선 블루프린트로 Widget Blueprint - UserWidget을 부모로 삼아 WBP_HPBar를 만들자.
생성한 후, Canvas Panel과 Progress Bar를 추가하고 위치를 조정한다.

그런 다음 그래프는 다음과 같은 형태로 만들어준다.



이렇게 WBP_HPBar의 최종 모습은 다음과 같다.


캐릭터 블루프린트로 돌아가서
Widget Component 추가 후 위치를 조정한다.
Beginplay에서 Widget의 OwningPlayer가 되도록 그림과 같이 만들어준다.
Gameplay Effect를 통해 Health Attribute의 값을 수정하고 반영되는지 확인한다.

