Unreal Engine/Gameplay Ability System

[UE] Gameplay Ability System -2- Attributes

KANTAM 2023. 5. 24. 01:55

https://github.com/tranek/GASDocumentation#concepts-as

 

GitHub - tranek/GASDocumentation: My understanding of Unreal Engine 5's GameplayAbilitySystem plugin with a simple multiplayer s

My understanding of Unreal Engine 5's GameplayAbilitySystem plugin with a simple multiplayer sample project. - GitHub - tranek/GASDocumentation: My understanding of Unreal Engine 5's Gamepl...

github.com

단순히 위의 문서를 보고 적은 것입니다. 차라리 위의 문서를 봐주세요. 저 영어 못 합니다.

 

4.3 Attributes

4.3.1 Attribute Definition

AttributesFGameplayAttributeData로 정의된 부동소수점 값이다. Attribute는 캐릭터의 체력의 양부터 물약을 가질 수 있는 소지수까지 모든 것을 나타낼 수 있다. 액터에 속한 게임플레이와 관련된 값일 경우 Attribute를 사용하는 것을 고려해야 한다. ASC가 변경을 예측할 수 있도록 일반적으로 GameplayEffect에 의해서만 수정되어야 한다.

AttributesAttributeSet안에서 정의되어야 한다.

 

4.3.2 BaseValue vs CurrentValue

AttributeBaseValueCurrentValue 2가지로 이루어져 있다. BaseValueAttribute의 영구적인 값이고 CurrentValueGameplayEffects에 의해 BaseValue에서 일시적으로 변경한 값이다.

BaseValue는 한 Attribute의 최대값이 아니다. 최대값은 새로운 Attribute로 설정해야 한다. 최대값, 최소값을 설정하는 방법은 FAttributeMetaData를 이용한 DataTable로 정의할 수 있다. 최대 최소값은 분리된 Attribute로 만들고 AttributeSetAttribute를 클램핑하는데 사용한다.

 

Attribute의 클램핑은 CurrentValue의 변경에는 PreAttributeChange()BaseValue의 변경에는 PostGameplayEffectExecute()가 사용된다.

 

영구적인 BaseValue의 변경에는 Instant GameplayEffect, CurrentValue의 변경에는 DurationInfinite GameplayEffect를 사용한다. 주기적인 GameplayEffectInstant GameplayEffect처럼 처리되며 BaseValue를 변경한다.

 

4.3.3 Meta Attributes

Meta AttributesAttribute와 상호작용할 임시 값에 대한 placeholder로 처리된다. 예를 들어 Meta Attributes를 데미지로 사용할 수 있다. GameplayEffect를 대신하여 MetaAttributes를 이용하여 체력 Attribute를 직접적으로 변경할 수 있다. 이렇게 하면 데미지가 들어왔을 경우 데미지의에 값을 조정하여 데미지에 버프를 하거나 디버프 처리도 GameplayEffectExecutionCalculation을 통해 가능하다. 방어력 Attribute를 가졌다면 그 만큼 데미지를 깍아서 처리한다.

 

Meta Attributes는 우리가 얼마나 많은 피해를 입혔는지와 피해로 우리는 무엇을 하는지 사이의 데미지와 치유와 같은 것들에 대한 좋은 논리적 분리를 제공한다. 이 논리적 분리는 Gameplay EffectsExecution Calculations이 타켓이 데미지를 어떻게 처리하는지 알아야할 필요가 없다는 의미이다. Gameplay Effect는 데미지가 몇 인지, AttributeSet에서 데미지를 어떻게 처리해야 하는지를 결정한다. 모든 캐릭터가 동일한 Attributes를 가질 수는 없다. 특히 AttributeSets의 하위 클래스라면 그렇다. 베이스 AttributeSet 클래스에선 체력 Attribute만 가질 수 있고 하위 클래스에서는 방여력 Attribute를 가질 수도 있다. 방어력을 가진 하위 AttributeSet은 베이스 AttributeSet과 달리 데미지를 받았을 경우 방어력과 분배할 것이다.

 

MetaAttributes는 좋은 디자인 패턴이지만 필수는 아니다. 만약 모든 데미지 인스턴스에 대한 하나의 Execution Calculation을 가지고 있거나 모든 캐릭터에서 공유되는 하나의 Attribute Set을 가지고 있다면, Execution Calculation 내부의 체력과 방어력에 대한 데미지 처리는 괜찮을 수 있다. 유연성을 희생하는 방법이지만 좋은 방법은 아니다.

 

4.3.4 Responding to Attribute Changes

Attribute가 변경되었을 경우, UI나 다른 게임플레이의 업데이트를 위하여 UAbilitySystemComponent::GetGameplayAttributeChangeDelegeate(FGameplayAttribut Attribute)를 사용할 수 있다. 이 함수는 Attribute가 변경되었을 때, 자동적으로 호출되며 우리가 바인드할 수 있는 델리게이트를 반환한다. 델리게이트는 FOnAttributeChangeData 파라미터와 NewValue, OldValue, FGameplayEffectModCallbackData를 제공한다.

Note: FGameplayEffectModCallbackData는 서버에서만 적용된다.

AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(AttributeSetBase->GetHealthAttribute()).AddUObject(this, &AGDPlayerState::HealthChanged);
virtual void HealthChanged(const FOnAttributeChangeData& Data);

샘플 프로젝트에서 GDPlayerState에서 체력이 0일 경우 죽음과 HUD의 업데이트를 위해 Attrinbute 델리게이트를 바인딩 했다.

샘플 프로젝트에는 이를 ASync 작업으로 래핑하는 커스텀 Blueprint노드가 포함되어 있다. 이것은 UMG위젯이 체력과 마나, 스태미나 값에 따라 업데이트 되도록 UI_HUD안에서 사용된다. AsyncTaskEndTask(), 위젯의 Destruct 이벤트 까지 계속해서 살아간다.

 

4.3.5 Derived Attributes

Attribute의 값 하나 혹은 모두를 만들기 위해서 하나 혹은 여러개의 Attributes에서 값을 Infinite GameplayEffectAttributeBasedMMC Modifiers를 사용하여 추출해야 한다. Derived Attributes는 종속된 Attribute가 업데이트될 때마다 자동적으로 갱신된다.

Derived Attribute의 모든 Modifiers의 공식은 모두 Modifier Aggregators로 같다. 특정 순서로 계산해야 하는 경우 MMC 내에서 모두 수행한다.

((CurrentValue + Additive) * Multiplicitive) / Division

Note: 만약 멀티플레이 클라이언트라면 Run Under One Process를 에디터 설정에서 꺼야한다. 그렇지 않으면 Derived Attributes는 해당 Attributes에 독립적인 Attributes가 다른 클라이언트에서 먼저 업데이트 되었다면 해당 클라이언트에서는 업데이트 되지 않는다.

밑의 예시는 Infinite GameplayEffectAttributesTestAttrB, TestAttrC로 부터 TestAttrA를 추출한다. 공식은 TestAttrA = (TestAttrA + TestAttrB) \* (2 \* TestAttrC)이다. TestAttrAAttributes의 데이터가 업데이트 될때마다 자동적으로 업데이트 된다.