0. 개요

특정 클래스에 종속적이지 않은 계산 방법을 도입하려 한다.

 

1. MMC(Modifier Magnitude Calculation)란?

기존에 최대 체력을 계산할 때 Vigor 뿐 아니라 레벨의 10배를 곱한 것을 추가하려 한다.

(이 프로젝트에서 레벨은 속성이 아니다)

속성이 아닌 값을 2차 속성을 계산하는 등, 임의의 계산식을 만들어서 속성 값을 계산할 수 있는데, 이를 MMC라고 한다.

 


- 종속성 제거

MMC가 플레이어 상태나 캐릭터 클래스에 종속적이지 않고 일반적으로 사용하는 데에 사용하려 한다.

MMC를 수정자(Modifier)에 추가하여 사용하면 종속성을 제거할 수 있다.

-> 전투 인터페이스를 구현하여 인터페이스를 전투에 참여하는 클래스에 부여하여 사용할 것이다.


 

2. 속성 값 계산 커스텀하기

 

(1) 플레이어 상태(Player State)에서 레벨 개념 추가

UCLASS()
class AURA_API AAuraPlayerState : public APlayerState, public IAbilitySystemInterface
{
	GENERATED_BODY()
	
public:
	AAuraPlayerState();

	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const  override;
	//~~
    
private:
	UPROPERTY(VisibleAnywhere, ReplicatedUsing = OnRep_Level)
	int32 Level = 1;

	UFUNCTION()
	void OnRep_Level(int32 OldLevel);
};

레벨 또한 복제(Replicate)를 하기 위해 노티파이를 등록한다.

void AAuraPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    DOREPLIFETIME(AAuraPlayerState, Level);
}

void AAuraPlayerState::OnRep_Level(int32 OldLevel)
{

}

 

 

(2) 적(AuraEnemy)에서 레벨 개념 추가

protected:
	UPROPERTY(EditAnywhere, BlueprintReadOnly, category = "Character Class Defaults")
	int32 Level = 1;

몬스터의 레벨은 서버에서 관리되기 때문에 노티파이가 필요없다.

 

 

(3) 전투 인터페이스(Combat Interface) 구현

전투 인터페이스를 호출하여 캐릭터들의 레벨을 Get 하는 등의 역할을 수행한다.

에디터에서 Unreal Interface를 상속받는 C++ 클래스를 생성한다.

함수 이름은 GetPlayerLevel로 한다.

(GetLevel을 사용하면 같은 이름을 가진 함수를 가림(Hiding))

class AURA_API ICombatInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	virtual int32 GetPlayerLevel();
};

 

int32 ICombatInterface::GetPlayerLevel()
{
    return 0;
}

GetPlayerLevel이 오버라이드 되지 않으면 기본으로 0을 리턴한다.

 

 

(3-1) AuraEnemy

적 캐릭터의 GetPlayerLevel을 구현한다.

int32 AAuraEnemy::GetPlayerLevel()
{
    return Level;
}

 

 

(3-2) AuraCharacter

	// 전투 인터페이스
	virtual int32 GetPlayerLevel() override;
	// 전투 인터페이스 끝

 

 

(3-3) AuraPlayerState

FORCEINLINE int32 GetPlayerLevel() const { return Level; }

FORCEINLINE은 전처리기가 Level을 가져오도록 해서 약간의 성능상 이득을 준다.

 

 

(3-4) AuraCharacter

void AAuraCharacter::GetPlayerLevel()
{
    const AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);

    return AuraPlayerState->GetPlayerLevel();
}