[GAS/sec6] Gameplay Effects
1. Gameplay Effect
1.1. 정의
UGameplayEffect
를 사용해 Attributes와 GameplayTags를 변경할 수 있다.
Gameplay Effect
- 데이터로 구성
- 블루프린트 base. (cpp 서브클래스X)
- modifiers와 executions을 통해 속성 변경
- modifier operation
- Add: 크기를 속성 값에 가산/감산
- Multiply: 속성 곱
- Divide: 속성 나눔
- Override: 속성 대체
- Magnitude Calculation Type
- Float
- 속성값 기반
- Custom Calculation Class
- Set by Caller
- Executions
- Gameplay Effect 계산 (사용자 정의. 두 개 이상의 속성 변경 가능)
- modifier operation
- 지속시간
- 일회성, modifier 즉시 적용됨 (즉각적인 효과)
- 일정 기간 동안 지속
- 영속성 (수동으로 제거하기 전까지!)
- 스택으로 효과 중첩 가능
- Abilities 부여
- gameplay Tag 추가
Gameplay Effect Spec을 사용해 최적화된 GameplayEffect를 구현할 수 있다.
1.2. 기본 구현
회복 아이템의 mesh와 overlap 효과를 cpp 파일에서 하드코딩으로 구현했다. UGameplayEffect
변수와 게임플레이 효과를 타켓에 적용시킬 ApplyEffectToTarget
함수를 구현해 이전 코드를 대체하는 것이 좋다. GameplayEffect를 활용하면 구현하기 쉽고 확장성이 높은 기능을 만들 수 있다.
1
2
// GameplayEffect의 대상이 되는 Ability System Component (Target은 대상 Actor)
UAuraAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Target);
- ASC에 적용할 수 있는 GameplayEffect 옵션
ApplyGameplayEffectToSelf
vsApplyGameplayEffectSpecToSelf
- 둘 다 GameplayEffect를 대상 ASC로 적용
ApplyGameplayEffectSpecToSelf
은 이전에 만들어진 게임플레이 효과 사양을 컴포넌트에 적용시킴
- 미리 GameplayEffect를 만들어두어야 함
- UGameplayEffect class 매개변수
- 레벨값
- Context (
FGameplayEffectContextHandle
)
- EffectContext를 포인터로 넘김 -> 게임플레이 태그를 얻고 적절한 속성 부여 가능
1 2 3 4 5 // ApplyGameplayEffectToSelf => GameplayEffect과 레벨 등을 모두 넘김 FActiveGameplayEffectHandle ApplyGameplayEffectToSelf(const UGameplayEffect *GameplayEffect, float Level, const FGameplayEffectContextHandle& EffectContext, FPredictionKey PredictionKey = FPredictionKey()); // ApplyGameplayEffectSpecToSelf => GameplayEffect의 주소값을 넘김 virtual FActiveGameplayEffectHandle ApplyGameplayEffectSpecToSelf(const FGameplayEffectSpec& GameplayEffect, FPredictionKey PredictionKey = FPredictionKey());
Gameplay Effect 적용 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void AAuraEffectActor::ApplyEffectToTarget(AActor* Target, TSubclassOf<UGameplayEffect> GameplayEffectClass)
{
/**
* GetAbilitySystemComponent(Actor)
* - Actor null이라면 null 반환
* - Actor의 캐스팅이 성공하면 인터페이스에 AbilitySystemComponent 반환
*/
UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Target);
if(TargetASC == nullptr) return;
check(GameplayEffectClass);
/** Gameplay Effect Context를 포함하는 wrapper 생성 */
FGameplayEffectContextHandle EffectContextHandle = TargetASC->MakeEffectContext();
/** EffectContextHandle에서 데이터 객체 가져옴 */
EffectContextHandle.AddSourceObject(this);
FGameplayEffectSpecHandle EffectSpecHandle = TargetASC->MakeOutgoingSpec(GameplayEffectClass, 1.0f, EffectContextHandle);
/** ApplyGameplayEffectSpecToSelf는 const 참조를 매개변수로 받으므로 Get으로 불러온 포인터에 역참조 연산자 사용*/
TargetASC->ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());
}
2. Duration Policy
2.1. Instance
GameplayEffect 를 상속받은 BP에서 지속성과 Modifiers, Executions 등을 설정할 수 있다. Health Potion에 대한 효과를 설정 중이므로 Instance로 구현, Modifier에서 AuraAttributeSet.Health를 더한다.
AuraEffectActor클래스에서 만들어준 UGameplayEffect
서브 클래스를 BP가 읽을 수 있도록 한다. BP에서 내부 속성값을 방금 만들어준 GameEffect BP로 설정하면 Health Potion이 지정한 효과를 얻는다.
BP_HealthPotion
실행 결과
참고) cpp 코드의
ApplyEffectToTarget
함수와 동일하게 구현된 BP
2.2. Has Duration
Duration Magnitude를 설정해 Gameplay Effect의 지속 시간을 줄 수 있다. ApplyEffectToTarget
함수에 새 GameplayEffect BP를 연결하기 위해 Duration 전용 변수를 선언한다.
1
2
3
// AuraEffectActor.h
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Applied Effects")
TSubclassOf<UGameplayEffect> DurationGameplayEffectClass;
2.3. Periodic
영구적으로 Gameplay Effect를 유지한다. 효과를 제거해도 이미 부여되었다면 취소되지 않는다.
- Period: 주기
- Execute Periodic Effect on Application: Effect 실행 시 즉시 적용
- Periodic Inhibition Policy: 태그를 기반으로 Gameplay Effect 제어
period 수치를 통해 duration gameplay effect를 보간할 수 있다. (eg. 1초동안 체력 50 상승, 0.1초마다 체력이 상승하도록 보간)
실행 결과
Effect Stacking
스택을 쌓지 않으면 game effect가 쌓이지 않고 중첩되어 Potion을 많이 먹을수록 효과가 매우 빨라지는,, 기현상이 나타난다.
- Stacking Type
- Aggregate by Source: Source에 따라 Game Effect 스택 제한
- 한 대상에 source의 일정 개수 이상 중첩 x, 다른 종류의 source라면 중첩 가능
- Aggregate by Target: Target에 따라 Game Effect 스택 제한
- 한 대상에 일정 스택 이상 중첩 x, source 종류 무관
- Stack Duration Refresh Policy
- 스택을 쌓을 때마다 기간 재설정, 스택을 쌓아도 기간이 만료되면 종료
- Stack Period Reset Policy:
- Stack Expiration Policy: 효과가 만료되면 모든 스택 삭제, 단일 스택 제거 선택, 스택을 지우지 않고 지속(영속성과 유사한 효과)
2.4. Infinite
1
2
3
// Infinite Game Effect BP를 만들기 위해 TSubclassOf 변수 생성
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Applied Effects")
TSubclassOf<UGameplayEffect> InfiniteGameplayEffectClass;
Leave a comment