[Unreal 5] GAS - Gameplay Effect Modifier
Gameplay Effect 는 Gameplay Tag 와 Attribute 를 수정하거나 변경할 수 있는 방법이다.
예를 들어 어떤 스킬이 있다면, 이 스킬이 주는 대미지나
어떤 포션이 있다면, 이 포션이 회복하는 값을 Gameplay Effect 를 통해 정의할 수 있다는 소리다.
이 Gameplay Effect 에는 Modifier 이라는 것이 존재하여 이름과 일맥상통하게 Attribute 를 수정할 수 있는데
Modifier 에는 4가지 종류가 있다.
1. Scalable Float
Scalable Float 은 값을 단순하게, 직접적으로 변경하는 방법이다.
아래 사진과 같이, 그냥 단순하게 특정한 값을 주어 Attribute 를 변경할 수 있다.
다만, GAS 는 Level 을 기준으로 만들도록 설계되어 있다.
예를 들어 스킬 레벨이 1이었을 때 10의 대미지를 입힌다면, 스킬 레벨이 2가 되면 20의 대미지를 입힐 수 있듯이
이렇게 Key:Value 의 형태로 Level:Value 를 정의할 수 있다.
따라서 Scalable Float Type 에 Curve Table 에셋을 위와 같이 만들어 사용하면, 어빌리티의 레벨에 따라 다른 값을 적용할 수 있게 된다.
Scalable Float Magnitude 는 순서대로 배율, 사용할 Curve Table 애셋, 해당 Curve Table 에서 사용할 데이터 커브 이다.
그냥 단순하게 적용해도 상관 없거나,
뭔가를 적용하기 전에 테스트하는 용도로 사용하면 좋다.
2. Attribute Base
Attribute Base 는 말 그대로 AttributeSet 을 값을 단순하게, 직접적으로 변경하는 방법이다.
위의 Gameplay Effect 는 Health 에 MaxHealth Attribute 를 덮어씌우는 작업을 수행한다.
즉 증감시킬 Rvalue 가 Attribute 라는 것이다.
Coefficient 로 이 Attribute 에도 계수를 적용하거나, 여기에도 Curve Table 을 사용하여 레벨 별로 계수를 정할 수도 있다.
예를 들어 "물리공격력" 이 "힘" 의 2배만큼 적용된다면, AttributeSet.MeleeAttack 을 AttributeSet.Strength 의 2배 Coefficient 로 적용할 수 있을 것이고,
레벨 별로 1~10에선 2배, 10~20에선 2.5배, 20~30에선 3배로 적용되게 하고 싶다면
Linear Curve Table 을 사용하여 이렇게 데이터를 정의하고, Coefficient 의 소스로 넣으면 되는 것이다.
위의 예제처럼 어떤 Attribute 값을 기준으로 적용이 되어야 한다면, 이 타입을 사용하는 것이 편리하다.
3. Custom Calculation Class
Custom Calculation Class 는 이런 단순한 연산이 아니라, 복잡한 연산이 필요한 경우 사용할 수 있다.
이 방법은 개발자가 직접 MMC(Modifier Magnitude Calculation) 클래스를 정의하여 적용해야 하는데,
이는아래의 클래스 (GameplayModMagnitudeCalculation) 를 상속하여 만들 수 있다.
직역하면 그냥 Modifier 를 이걸로 계산해라 이 말이다.
언리얼 엔진이 으레 그렇듯, 여기에도 사용법이 정해져 있는데
CalculateBaseMagnitude_Implementation 함수 내에 원하는 연산을 만들면 된다.
필요한 값이 있으면 필요한 값을 가져오면 되고, Gameplay Effect Spec 이 주어지므로 GE 관련하여 필요한 것이 있으면 이 Spec 을 통해 가져오면 된다.
위 소스는 Vigor 스탯과 레벨을 가지고 최대 체력을 계산하는 MMC 이다.
주로 복잡한 계산이 필요한 경우 MMC를 만들어 사용할 때가 많다.
4. Set by Caller
Set by Caller 는 이 Gameplay Effect Spec 을 만드는 Code 혹은 Blueprint 에서 정의된 값을 사용하겠다는 것이다.
예를 들어, 아래와 같이 Gameplay Effect 를 만든다고 생각해 보자.
위의 코드는 DamageEffectClass 라는 Gameplay Effect Class 에 Set By Caller 타입으로 Magnitude 를 넘겨주고 있다.
넘겨주는 방법은 위 코드에서 볼 수 있듯, UAbilitySystemBlueprintLibrary::AssignTagSetByCallerMagnitude 함수를 사용하면 된다. 물론 이 외에도 UAbilitySystemBlueprintLibrary::AssignTagSetByCallerMagnitude 를 사용해도 되는데, 두 함수의 차이는 데이터 식별에 Gameplay Tag 를 사용할 것인지 그냥 이름을 사용할 것인지의 차이이다.
Gameplay Effect 에도 Set by Caller 를 선택해 보면, Data Name 과 Data Tag 가 있다.
여기서 어떤 태그의 데이터를 사용할지 선택하면 된다.
위의 코드에서는 Damage 태그를 선택했기 때문에, 여기서 Damage 태그를 선택해야 위에서 넘긴 데이터를 받을 수 있게 되는 것이고, 이것 역시 Key : Value 의 형태로 적용된다고 생각하면 이해하기 쉽다.
MMC는 계산 방식이 클래스 내부에 정해져 있는 반면, Set by Caller 는 Ability 의 비즈니스 로직 내에서도 사용이 가능하므로 상황에 따라 유연하게 사용할 수 있다.