1. 레벨업

(1) PlayerInterface에서 레벨업 함수 선언

class AURA_API IPlayerInterface
{
	GENERATED_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	UFUNCTION(BlueprintNativeEvent)
	void AddToXP(int32 InXP);

	UFUNCTION(BlueprintNativeEvent)
	void LevelUp();
};

 

 

(2) PlayerInterface에서 XP에 대한 Getter 함수 선언

public:
	UFUNCTION(BlueprintNativeEvent)
	int32 GetXP() const;

 

(2-1) AuraCharacter에서 XP Getter 함수 정의

	// 플레이어 인터페이스
	virtual void AddToXP_Implementation(int32 InXP) override;
	virtual void LevelUp_Implementation() override;
	virtual int32 GetXP_Implementation() const override;
	// 플레이어 인터페이스 끝
int32 AAuraCharacter::GetXP_Implementation() const
{
    AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);
    AuraPlayerState->GetXP();
}

Aura 캐릭터에서 AuraPlayerState를 사용하여 XP Getter 함수를 호출한다.

 

 

(3) AttributeSet의 LevelUpInfo를 사용하여 XP에 해당하는 레벨 찾기

(3-1) PlayerInterface에서 FindLevelForXP 함수 선언

public:
	UFUNCTION(BlueprintNativeEvent)
	int32 FindLevelForXP(int32 InXP) const;

 

 

(3-2) AuraCharacter에서 AuraPlayerState의 LevelUpInfo에 접근

	virtual int32 FindLevelForXP_Implementation(int32 InXP) const override;
	// 플레이어 인터페이스 끝
int32 AAuraCharacter::FindLevelForXP_Implementation(int32 InXP) const
{
    AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);
    return AuraPlayerState->LevelUpInfo->FindLevelForXP(InXP);
}

LevelUpInfo 내의 함수인 FindLevelForXP 함수를 호출한다.

 

 

(4) AuraAttributeSet의 PostGameplayEffectExecute 함수

경험치와 레벨업을 계산하는 부분을 수정한다.

    // 경험치 계산
    if (Data.EvaluatedData.Attribute == GetIncomingXPAttribute())
    {
        const float LocalIncomingXP = GetIncomingXP();
        SetIncomingXP(0);

        // TODO : 레벨업 체크 필요

        // Source Character는 보유자, GA_ListenForEvents가 GE_EventBasedEffect를 사용하여 IncomingXP를 더하는 중
        if (Props.SourceCharacter->Implements<UPlayerInterface>() && Props.SourceCharacter->Implements<UCombatInterface>())
        {
            const int32 CurrentLevel = ICombatInterface::Execute_GetCharacterLevel(Props.SourceCharacter);
            const int32 CurrentXP = IPlayerInterface::Execute_GetXP(Props.SourceCharacter);

            // 현재 경험치에 새 경험치를 더한 레벨 계산
            const int32 NewLevel = IPlayerInterface::Execute_FindLevelForXP(Props.SourceCharacter, CurrentXP + LocalIncomingXP);
            
            // 레벨업 몇 번
            const int32 NumLevelUps = NewLevel - CurrentLevel;

            // 레벨업 숫자 체크
            if (NumLevelUps > 0)
            {
                // TODO :
                // 속성 포인트 보상 값 가져오기 / GetAttributePointsReward()
                // 스펠 포인트 보상 값 가져오기 / GetSpellPointsReward()
                // 플레이어 레벨에 추가하기 / AddToPlayerLevel()
                // 속성 및 스펠 포인트에 더하기 // AddToAttributesPoints(), AddToSpellPoints()
                // 체력과 마나 회복하기

                IPlayerInterface::Execute_LevelUp(Props.SourceCharacter);
            }
            

            IPlayerInterface::Execute_AddToXP(Props.SourceCharacter, LocalIncomingXP);
        }
    }

 

 

2. 플레이어 인터페이스에 함수 추가

(1) PlayerInterface에서 함수 선언

이제 위의 TODO를 참고하고 PlayerInterface에 함수를 선언한다.

public:
	UFUNCTION(BlueprintNativeEvent)
	int32 FindLevelForXP(int32 InXP) const;

	UFUNCTION(BlueprintNativeEvent)
	int32 GetXP() const;

	UFUNCTION(BlueprintNativeEvent)
	int32 GetAttributePointsReward() const;

	UFUNCTION(BlueprintNativeEvent)
	int32 GetSpellPointsReward() const;

	UFUNCTION(BlueprintNativeEvent)
	void AddToPlayerLevel(int32 InLevel);

	UFUNCTION(BlueprintNativeEvent)
	void AddToXP(int32 InXP);

	UFUNCTION(BlueprintNativeEvent)
	void AddToAttributePoints(int32 InAttributePoints);

	UFUNCTION(BlueprintNativeEvent)
	void AddToSpellPoints(int32 InSpllPoints);

	UFUNCTION(BlueprintNativeEvent)
	void LevelUp();
};

 

 

(2) AuraCharacter에서 함수 정의

	// 플레이어 인터페이스
	virtual void AddToXP_Implementation(int32 InXP) override;
	virtual void LevelUp_Implementation() override;
	virtual int32 GetXP_Implementation() const override;
	virtual int32 FindLevelForXP_Implementation(int32 InXP) const override;
	virtual int32 GetAttributePointsReward_Implementation(int32 Level) const override;
	virtual int32 GetSpellPointsReward_Implementation(int32 Level) const override;
	virtual void AddToPlayerLevel_Implementation(int32 InLevel) override;
	virtual void AddToAttributePoints_Implementation(int32 InAttributePoints) override;
	virtual void AddToSpellPoints_Implementation(int32 InSpellPoints) override;
	// 플레이어 인터페이스 끝

 

 

(2-1) 레벨업 보상 속성 포인트 & 스펠 포인트 가져오기

int32 AAuraCharacter::GetAttributePointsReward_Implementation(int32 Level) const
{
    const AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);
    return AuraPlayerState->LevelUpInfo->LevelUpInformation[Level].AttributePointAward;
}

int32 AAuraCharacter::GetSpellPointsReward_Implementation(int32 Level) const
{
    const AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);
    return AuraPlayerState->LevelUpInfo->LevelUpInformation[Level].SpellPointAward;
}

AuraPlayerState가 가지고 있는 LevelUpInfo에 접근해서 레벨에 맞는 보상을 가져온다.

 

 

(2-2) 레벨 증가

void AAuraCharacter::AddToPlayerLevel_Implementation(int32 InLevel)
{
    AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);
    AuraPlayerState->AddToLevel(InLevel);
}

 

 

(3) AuraPlayerState의 PostGameplayEffectExecute 함수에서 경험치 및 레벨 계산

// 경험치 계산
if (Data.EvaluatedData.Attribute == GetIncomingXPAttribute())
{
    const float LocalIncomingXP = GetIncomingXP();
    SetIncomingXP(0);

    // TODO : 레벨업 체크 필요

    // Source Character는 보유자, GA_ListenForEvents가 GE_EventBasedEffect를 사용하여 IncomingXP를 더하는 중
    if (Props.SourceCharacter->Implements<UPlayerInterface>() && Props.SourceCharacter->Implements<UCombatInterface>())
    {
        const int32 CurrentLevel = ICombatInterface::Execute_GetCharacterLevel(Props.SourceCharacter);
        const int32 CurrentXP = IPlayerInterface::Execute_GetXP(Props.SourceCharacter);

        // 현재 경험치에 새 경험치를 더한 레벨 계산
        const int32 NewLevel = IPlayerInterface::Execute_FindLevelForXP(Props.SourceCharacter, CurrentXP + LocalIncomingXP);
        
        // 레벨업 몇 번
        const int32 NumLevelUps = NewLevel - CurrentLevel;

        // 레벨업 숫자 체크
        if (NumLevelUps > 0)
        {
            // 레벨업 보상
            const int32 AttributePointsReward = IPlayerInterface::Execute_GetAttributePointsReward(Props.SourceCharacter, CurrentLevel);
            const int32 SpellPointsReward = IPlayerInterface::Execute_GetSpellPointsReward(Props.SourceCharacter, CurrentLevel);

            // 레벨 더하기
            IPlayerInterface::Execute_AddToPlayerLevel(Props.SourceCharacter, NumLevelUps);
            IPlayerInterface::Execute_AddToAttributePoints(Props.SourceCharacter, AttributePointsReward);
            IPlayerInterface::Execute_AddToSpellPoints(Props.SourceCharacter, SpellPointsReward);

            // 체력과 마나 회복하기
            SetHealth(GetMaxHealth());
            SetMana(GetMaxMana());

            IPlayerInterface::Execute_LevelUp(Props.SourceCharacter);
        }
        

        IPlayerInterface::Execute_AddToXP(Props.SourceCharacter, LocalIncomingXP);
    }
}

이제 생성한 함수들을 호출해서 레벨과 속성포인트, 스펠포인트를 가져와 부여하게 한다.