3 minute read


8. RPG Attribute


Modifier


8.3. Attribute Based Modifiers


Modifiers와 속성

image

  • Attribute Based: 다른 속성을 기반으로 속성을 변경할 수 있는 기능 제공



image

image

테스트용 Actor_BP와 GE_BP. Modifier 배열을 확장해 여러 효과를 중첩시킬 수 있다.

  • Attribute to Capture: overlap 시 대상이 어느 속성을 가져올 것인지 결정

    • eg) Target에게 Strength를 더함
  • Attribute Source: overlap 시 효과를 캐릭터에게 적용시키므로 Target 선택

  • Snapshot: 속성을 언제 캡처해야 하는지, 언제 해당 속성 값을 사용할지 결정


8.4. Order of Operations


image

operator를 변경해 Actor에게 부여하는 효과를 확장시킬 수 있다. Modifier는 순서대로 적용되므로 여러 개의 Modifier가 있을 경우 연산 순서에 따라 결과물이 달라질 수 있다.

  • eg1) health(10) + vigor(9) * strength(10) -> 190

  • eg2) health(10) * strength(10) + vigor(9) -> 109


8.5. Coefficients


image

  • Attribute Based Magnitude

    • 계수(C)

    • 사전 덧셈 값(Pre)

    • 사후 덧셈 값(Post)

    • eg) C( attribute + Pre ) + Post


Other Attributes


8.6. Secondary Attrubutes


  • Attributes 분류

    • Primary Attributes: 종속되지 않는 독립적인 속성

      • Str, Int, Res, Vig
    • Secondary Attributes: 다른 속성에서 파생되는 속성

      • Armor(Res)

      • Armor Penetration(Res): 회복력에 따라 달라짐, 일정 비율 무시

      • Block Chance(Armor): 들어오는 대미지는 절반으로 줄임

      • Critical Hit Chance(AP): 피해를 두배로 늘리고 치명타 보너스 추가

      • Critical Hit Damage(AP): 치명타 보너스 대미지 증가

      • Critical Hit Resistance(Armor): 치명타 확률 감소

      • Health Regeneration(Vig), Mana Regeneration(Int), Max Health(Vig), Max Mana(Int)



속성 추가하는 과정 ```c++ /* * AuraAttributeSet.h */ // 1. UPROPERTY와 속성, 속성 접근자 선던 (UPROPERTY에는 해당 속성에 대한 notify가 있어야 함) UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Armor, Category = "Secondary Attributes") FGameplayAttributeData Armor; ATTRIBUTE_ACCESSORS(UAuraAttributeSet, Armor); // 노티파이 함수 선언 UFUNCTION() void OnRep_Armor(const FGameplayAttributeData& OldArmor) const; /* * AuraAttributeSet.cpp */ // 각 속성의 네트워크 복제 설정 DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, Armor, COND_None, REPNOTIFY_Always); // 노티파이를 통해 다음 사항을 알릴 수 있음(새 속성 값, 이전 속성 값) void UAuraAttributeSet::OnRep_Armor(const FGameplayAttributeData& OldArmor) const { GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, Armor, OldArmor); } ```


8.7. Derived Attributes


Secondary Attributes를 캐릭터에게 적용시키기 위해 CharacterBase 클래스에 DefaultSecondaryAttributes에 대한 TSubclassOf를 적용시킨다. (Secondary Attributes는 Primary의 영향을 받으므로 PA가 초기화된 후 초기화시켜야 하기 때문! 클래스가 두 개 필요하다)


Code ``` c++ /* * 1. AuraCharacterBase.h */ UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Attributes") TSubclassOf DefaultPrimaryAttributes; UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Attributes") TSubclassOf DefaultSecondaryAttributes; /* * 2. AuraCharacter.cpp */ void AAuraCharacter::InitAbilityActorInfo() { AAuraPlayerState* AuraPlayerState = GetPlayerState(); check(AuraPlayerState); AuraPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(AuraPlayerState, this); // AuraPlayerState에 대한 AuraASC를 캐스트해 AbilityActorInfoSet를 호출 => 정상적으로 호출되었다면 잘 설정된 것임 Cast(AuraPlayerState->GetAbilitySystemComponent())->AbilityActorInfoSet(); AbilitySystemComponent = AuraPlayerState->GetAbilitySystemComponent(); AttributeSet = AuraPlayerState->GetAttributeSet(); if(AAuraPlayerController* AuraPlayerController = Cast(GetController())) { if(AAuraHUD* AuraHUD = Cast(AuraPlayerController->GetHUD())) { AuraHUD->InitOverlay(AuraPlayerController, AuraPlayerState, AbilitySystemComponent, AttributeSet); } // AuraController와 AuraHUD가 올바르게 캐스팅 된 이후 캐릭터의 속성을 불러옴 InitializeDefaultAttrubutes(); } } /* * 3. AuraCharacterBase.cpp */ void AAuraCharacterBase::ApplyEffectToSelf(TSubclassOf GameplayEffectClass, float Level) const { // GAS 및 DefaultSecondaryAttributes가 유효한지 확인 check(IsValid(GetAbilitySystemComponent())); check(GameplayEffectClass); // MakeEffectContext() 함수를 통해 ContextHandle 생성 const FGameplayEffectContextHandle ContextHandle = GetAbilitySystemComponent()->MakeEffectContext(); // DefaultSecondaryAttributes의 핸들을 만듦 const FGameplayEffectSpecHandle SpecHandle = GetAbilitySystemComponent()->MakeOutgoingSpec(GameplayEffectClass, Level, ContextHandle); // 대상(캐릭터의 GAS)에게 SpecHandle의 데이터 전달 GetAbilitySystemComponent()->ApplyGameplayEffectSpecToTarget(*SpecHandle.Data.Get(), GetAbilitySystemComponent()); } void AAuraCharacterBase::InitializeDefaultAttrubutes() const { /* Primary Attributes와 Secondary Attributes를 한 번에 초기화 */ ApplyEffectToSelf(DefaultPrimaryAttributes, 1.f); ApplyEffectToSelf(DefaultSecondaryAttributes, 1.f); } ``` </details>
> > **알아두자 속성 초기화 동작과정!** > > 1. 캐릭터 베이스 클래스 헤더에 초기화 함수 선언 > > 2. 캐릭터 클래스의 ASC 초기화 함수의 구현부 말단에 속성 초기화 함수 호출 > > 3. 캐릭터 베이스 클래스의 속성 초기화 구현부에서 ASC에 접근 -> 해당 타겟에 적용 > >

> > **🔔리마인드🔔** > > GAS는 게임에 영향을 미치는 객체를 Gameplay Effect로 분리해 관리한다. > >
> > **GE 관련 핸들** > > * **Gameplay Effect Context**: GameEffect의 Insgator와 대상에 대한 정보(함수, 멤버변수 등)가 저장 > > * **Gameplay Effect Spec**: GE와 관련된 정보 > >
> > `ContextHandle`이 대상에 대한 정보를 가져오면 해당 정보를 GESpec에 담고, `SpecHandle`을 통해 활용한다(GAS는 간접적으로 다룬다!). > > [**GAS의 Attribute 및 Effect 문서**](https://dev.epicgames.com/documentation/ko-kr/unreal-engine/gameplay-attributes-and-gameplay-effects-for-the-gameplay-ability-system-in-unreal-engine?application_version=5.0)

*GE_AuraSecondaryAttributes* ![image](https://github.com/user-attachments/assets/57196891-31bd-4b21-bf6b-abc5e8e4136b) * Duration Policy를 Infinite로 설정 * eg) Modifiers[0] * `Amor` Attribute를 조작 * Base가 될 Attribute를 기반으로 override * 계수: Base Attribute에 0.5를 곱하고 6.0을 더한 값 * Backing Attribute * Base가 될 Attribute: `Resilience` * Attribute 계산 결과: `Target`에 적용 * *res) Aura 캐릭터의 Amor 값에 0.25 * (2 + `Res`) + 6 = 9.5 적용* ![image](https://github.com/user-attachments/assets/41d5236b-2587-42ef-bf60-2a89217e88b2)

Leave a comment