3 minute read


Unreal Engine 5 - Gameplay Ability System - Top Down RPG

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 즉시 적용됨 (즉각적인 효과)
    • 일정 기간 동안 지속
    • 영속성 (수동으로 제거하기 전까지!)
  • 스택으로 효과 중첩 가능
  • 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);

image

  • ASC에 적용할 수 있는 GameplayEffect 옵션


ApplyGameplayEffectToSelf vs ApplyGameplayEffectSpecToSelf

  • 둘 다 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


image

GameplayEffect 를 상속받은 BP에서 지속성과 Modifiers, Executions 등을 설정할 수 있다. Health Potion에 대한 효과를 설정 중이므로 Instance로 구현, Modifier에서 AuraAttributeSet.Health를 더한다.


AuraEffectActor클래스에서 만들어준 UGameplayEffect 서브 클래스를 BP가 읽을 수 있도록 한다. BP에서 내부 속성값을 방금 만들어준 GameEffect BP로 설정하면 Health Potion이 지정한 효과를 얻는다.


BP_HealthPotion

image


실행 결과

녹화_2024_05_07_15_54_48_985


참고) cpp 코드의 ApplyEffectToTarget 함수와 동일하게 구현된 BP

image


2.2. Has Duration


image

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를 유지한다. 효과를 제거해도 이미 부여되었다면 취소되지 않는다.


image

  • Period: 주기
  • Execute Periodic Effect on Application: Effect 실행 시 즉시 적용
  • Periodic Inhibition Policy: 태그를 기반으로 Gameplay Effect 제어


period 수치를 통해 duration gameplay effect를 보간할 수 있다. (eg. 1초동안 체력 50 상승, 0.1초마다 체력이 상승하도록 보간)


실행 결과

_2024_05_07_17_00_45_625-ezgif com-video-to-gif-converter


Effect Stacking

image

스택을 쌓지 않으면 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