[UE-GAS] MMC(ModMagnitudeCalculation)에 대해

ChangJin·2024년 11월 20일

Unreal Engine - GAS

목록 보기
4/6
post-thumbnail

UGameplayModMagnitudeCalculation (MMC)는 언리얼 엔진의 Gameplay Ability System(GAS) 프레임워크에서 Attribute의 Modifier를 적용할때 커스텀 계산식을 사용하기 위해 쓰입니다. 이번 글에서는 MMC의 구조와 사용법, 그리고 레벨 기반 커스텀 계산식을 구현한 예제를 소개합니다.


1. MMC란?

MMC(UGameplayModMagnitudeCalculation)GameplayEffect효과 크기(Magnitude)를 동적으로 계산하는 데 사용됩니다. 이는 단순히 기본값이나 계수를 설정하는 방식보다 유연하며, 다음과 같은 계산을 수행할 수 있습니다.

  • 속성(Attribute) 기반 계산: 플레이어의 스탯(예: Strength, Intelligence 등)을 기반으로 계산.
  • 외부 요인 포함: 예를 들어, 플레이어 레벨, 태그, 환경 요소 등을 고려.
  • 커스텀 논리 구현: 고유한 게임 메커니즘을 MMC로 처리.

활력, 지능에 따라 체력과 마나량이 달라지지만 거기에 더해 플레이어의 레벨도 체력양과 마나량에 영향을 주도록 만들고자 했습니다.


2. MMC 구조

MMC는 다음과 같은 메서드를 오버라이드하여 커스텀 계산식을 정의합니다.

CalculateBaseMagnitude_Implementation

virtual float CalculateBaseMagnitude_Implementation(const FGameplayEffectSpec& Spec) const override;
  • Spec 객체는 GameplayEffect 실행에 필요한 데이터와 태그를 포함합니다.
  • 계산 결과로 기본 Magnitude 값을 반환합니다.

3. 코드 예제: 레벨 기반 커스텀 계산식

다음은 Intelligence 속성과 플레이어 레벨을 기반으로 마나 최대치(Max Mana)를 계산하는 예제입니다.

헤더 파일 정의

#pragma once

#include "CoreMinimal.h"
#include "GameplayModMagnitudeCalculation.h"
#include "MMC_MaxMana.generated.h"

UCLASS()
class YOURGAME_API UMMC_MaxMana : public UGameplayModMagnitudeCalculation
{
	GENERATED_BODY()

public:
	UMMC_MaxMana();

protected:
	virtual float CalculateBaseMagnitude_Implementation(const FGameplayEffectSpec& Spec) const override;

private:
	FAggregatorCaptureDefinition IntelligenceDefinition;
};

CPP 파일 구현

#include "MMC_MaxMana.h"
#include "YourAttributeSet.h"
#include "CombatInterface.h"

float UMMC_MaxMana::CalculateBaseMagnitude_Implementation(const FGameplayEffectSpec& Spec) const
{
	// 1. 소스 및 타겟 태그 가져오기
	const FGameplayTagContainer* SourceTags = Spec.CapturedSourceTags.GetAggregatedTags();
	const FGameplayTagContainer* TargetTags = Spec.CapturedTargetTags.GetAggregatedTags();

	// 2. 계산 매개변수 설정
	FAggregatorEvaluateParameters EvaluateParams;
	EvaluateParams.SourceTags = SourceTags;
	EvaluateParams.TargetTags = TargetTags;

	// 3. Intelligence 속성 캡처 및 초기화
	float Intelligence = 0.0f;
	GetCapturedAttributeMagnitude(IntelligenceDefinition, Spec, EvaluateParams, Intelligence);
	Intelligence = FMath::Max<float>(Intelligence, 0.0f);

	// 4. CombatInterface를 통해 플레이어 레벨 가져오기
	ICombatInterface* CombatInterface = Cast<ICombatInterface>(Spec.GetContext().GetSourceObject());
	const int32 PlayerLevel = CombatInterface ? CombatInterface->GetPlayerLevel() : 1; // 기본 레벨 1

	// 5. 계산식 적용: 기본값 + Intelligence + PlayerLevel
	return 50 + 2.5f * Intelligence + 10.f * PlayerLevel;
}

4. 주요 코드 설명

1) 속성(Attribute) 캡처

MMC는 GameplayEffect 실행 시 관련 속성을 캡처하여 계산에 사용합니다.

float Intelligence = 0.0f;
GetCapturedAttributeMagnitude(IntelligenceDefinition, Spec, EvaluateParams, Intelligence);
  • IntelligenceDefinition: 캡처할 속성을 정의한 객체.
  • Spec: GameplayEffect의 실행 맥락(Context) 데이터를 포함.
  • EvaluateParams: 소스와 타겟 태그를 포함한 매개변수.

2) CombatInterface를 통한 레벨 정보 가져오기

Spec.GetContext().GetSourceObject()를 사용하여 소스 객체에서 데이터를 추출합니다.

ICombatInterface* CombatInterface = Cast<ICombatInterface>(Spec.GetContext().GetSourceObject());
const int32 PlayerLevel = CombatInterface ? CombatInterface->GetPlayerLevel() : 1;
  • CombatInterface는 인터페이스를 통해 플레이어 레벨 데이터를 제공합니다.
  • 객체가 없을 경우 기본값 1을 반환합니다.

3) 계산식

기본값(40), Intelligence 기반 값(1.25배), 레벨 기반 값(5배)을 조합하여 최종 결과를 반환합니다.

return 40 + 1.25f * Intelligence + 5.f * PlayerLevel;

5. FGameplayEffectAttributeCaptureDefinition

MMC에서 속성을 캡처하기 위해 사용되는 FGameplayEffectAttributeCaptureDefinition에 대해 살펴봅시다.

정의

USTRUCT(BlueprintType)
struct GAMEPLAYABILITIES_API FGameplayEffectAttributeCaptureDefinition
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditDefaultsOnly, Category=Capture)
	FGameplayAttribute AttributeToCapture;

	UPROPERTY(EditDefaultsOnly, Category=Capture)
	EGameplayEffectAttributeCaptureSource AttributeSource;

	UPROPERTY(EditDefaultsOnly, Category=Capture)
	bool bSnapshot;
};

구성 요소

  1. AttributeToCapture: 캡처할 속성(Attribute)을 정의.
  2. AttributeSource: 캡처 위치(Source/Target)를 지정.
    • Source: 효과를 생성한 객체.
    • Target: 효과를 받는 객체.
  3. bSnapshot: 속성의 스냅샷 여부를 설정.

6. UAbilitySystemComponent와 연결

MMC는 UAbilitySystemComponent와 함께 작동하여 GameplayEffectSpec을 생성하고 적용합니다.

GameplayEffectSpec 생성

FGameplayEffectSpecHandle SpecHandle = AbilitySystemComponent->MakeOutgoingSpec(GameplayEffectClass, Level, Context);
  • MakeOutgoingSpec: GameplayEffectSpec를 생성합니다.
  • Context: EffectContext 객체로, 소스 및 타겟 데이터를 포함합니다.

7. 결론

MMC는 GAS의 Attribute Modifier의 계산식을 커스터마이징하는 데 유용한 도구입니다. Attribute 기반 계산, Tag와 데이터를 활용한 계산, 레벨 기반 추가 계산 등을 구현할 수 있습니다.

profile
게임 프로그래머

0개의 댓글