Unreal - 경험치, 레벨업 구현하기

2025. 12. 2. 20:40·Unreal 프로젝트 다이어리/두번째 프로젝트

구현내용

플레이어의 경험치 와 레벨업 시스템을 구현하였습니다

 

사용한 클래스

StatComponent 플레이어의 스탯관련부분을 담당하는 커스텀 컴포넌트

 

 

구현

C++구현

필요한 .h 선언

UPROPERTY()
float currentExp = 0.f;

UPROPERTY()
float expNextLevel = 100.f;

UPROPERTY(EditAnywhere, Category="Level")
int32 maxLevel = 30;

UFUNCTION()
void LevelUp();

UFUNCTION()
void CalcExpNextLev();

UFUNCTION()
void AddExp(float amount);

UFUNCTION()
void MaxLevel();

 

경험치가 소수로 나오면 이상하니 내림하여 정수로 만들고 레벨이 올라갈수록 (1.2% -> 20%) 증가한 

레벨이 올라갈수록 경험치가 곱셈으로 점점 커지는 구조를 만들어주었습니다

void UStatComponent::CalcExpNextLev()
{
	float baseExp = 100.f;
	float growRate = 1.2f;
	expNextLevel = FMath::Floor(baseExp * FMath::Pow(growRate, float(level - 1)));
}

 

매개변수값 amount만큼 경험치를 더합니다

또한 동일하게 소수점을 버리고 정수형으로 반환하며 max레벨이 될떄까지 반복합니다

void UStatComponent::AddExp(float amount)
{
	currentExp = FMath::FloorToFloat(currentExp + amount);

	while (currentExp >= expNextLevel && level < maxLevel)
	{
		currentExp -= expNextLevel;
		LevelUp();
	}
	if (level >= 30)
		MaxLevel();

	if (onExpChanged.IsBound())
		onExpChanged.Broadcast(currentExp, expNextLevel, level);
}

 

 

캐릭터의 레벨업 함수입니다

레벨을 1 증가시키며 레벨에 따른 스탯을 적용합니다

void UStatComponent::LevelUp()
{
	level++;

	ApplyLevelStat();
	TriggerBlink();
	GetLevelUpPoints();

	//레벨 경험치 공식 -> 1.2배
	CalcExpNextLev();
	//////////////////////////
	currentExp = FMath::FloorToFloat(currentExp);

	//브로드캐스팅
	onExpChanged.Broadcast(currentExp, expNextLevel, level);
	onCenterNotiChanged.Broadcast(level, "", "");
	onLevelChanged.Broadcast(level);
	onAbilityPointChanged.Broadcast(currentAbilityPoint, totalAbilityPoint);
	onStatPointChanged.Broadcast(currentStatPoint, totalStatPoint);
	onAttackPowerChanged.Broadcast(stats[EBaseStatType::AttackPower].EntryTotal(), stats[EBaseStatType::AttackPower].EntryTotal());

	RestoreHpPosture();
}

 

레벨의 짝수와 홀수에 따라서 지급되는 스탯포인트와 어빌리티포인트를 다르게 계산해주었습니다

void UStatComponent::GetLevelUpPoints()
{
	if (level <= 0)
		return;

	bool bIsEven = (level % 2 == 0); //짝

	int32 statGain = 0;
	int32 abilityGain = 0;

	if (bIsEven)
	{
		statGain = 3;
		abilityGain = 2;
	}
	else
	{
		statGain = 2;
		abilityGain = 1;
	}
	AddStatPoint(statGain);
	AddAbilityPoint(abilityGain);

	//ui갱신 예약
	UpdateStatPointUI();
	UpdateAbilityPointUI();
}

 

위젯

캐릭터 메인 위젯의 센터위쪽을 담당할 노티위젯을 만들어주었습니다

 

메인위젯의 모습

 

위젯c++

UPROPERTY(meta = (BindWidget))
class UOverlay* Overlay_Base;

UPROPERTY(meta = (BindWidget))
class UTextBlock* Text_Top;

UPROPERTY(meta = (BindWidget))
class UTextBlock* Text_Bottom;

UPROPERTY(meta = (BindWidgetAnim), Transient)
class UWidgetAnimation* FadeLevel;

UPROPERTY(meta = (BindWidgetAnim), Transient)
class UWidgetAnimation* FadeHighLight;

UFUNCTION()
void UpdateCenterWidget(int32 currentLevel = -1, const FString& mapExplantion = "", const FString& mapName = "");

UFUNCTION()
void OnLevelAnimFinished_Internal();

bool bIsFadingOut = false;

 

애니메이션 순서를 FadeLevel -> FadeHighLight -> FadeLevel(리버스) 로 설정하였습니다

델리게이트를 사용하여 순차적으로 실행되도록 구현하였습니다

void UCenterNotiWidget::NativeConstruct()
{
	Super::NativeConstruct();

	Overlay_Base->SetVisibility(ESlateVisibility::Collapsed);

	FWidgetAnimationDynamicEvent finishFadeEv;
	finishFadeEv.BindDynamic(this, &UCenterNotiWidget::OnLevelAnimFinished_Internal);
	BindToAnimationFinished(FadeLevel, finishFadeEv);
	BindToAnimationFinished(FadeHighLight, finishFadeEv);

}
//애니메이션순서 FadeLevel -> FadeHighLight -> FadeLevel(Reverse)
void UCenterNotiWidget::UpdateCenterWidget(int32 currentLevel, const FString& mapExplantion, const FString& mapName)
{
	Overlay_Base->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
	//레벨용
	if (currentLevel)
	{
		if (Text_Top)
			Text_Top->SetText(FText::FromString(TEXT("Level Up!")));
		if (Text_Bottom)
		{
			FString levelText = FString::Printf(TEXT("Lv . %d"), currentLevel);
			Text_Bottom->SetText(FText::FromString(levelText));
		}
		bIsFadingOut = false;
		PlayAnimation(FadeLevel, 0.f, 1, EUMGSequencePlayMode::Forward, 3.f);
		return;
	}

	//맵용
	if (!mapExplantion.IsEmpty() && !mapName.IsEmpty())
	{
		if(Text_Top)
			Text_Top->SetText(FText::FromString(mapExplantion));
		if (Text_Bottom)
			Text_Bottom->SetText(FText::FromString(mapName));
	}
}

void UCenterNotiWidget::OnLevelAnimFinished_Internal()
{
	if (!bIsFadingOut && GetAnimationCurrentTime(FadeLevel) >= FadeLevel->GetEndTime())
	{
		bIsFadingOut = true;
		PlayAnimation(FadeHighLight, 0.f, 1, EUMGSequencePlayMode::Forward, 3.f);
	}
	else if (bIsFadingOut && GetAnimationCurrentTime(FadeHighLight) >= FadeHighLight->GetEndTime())
	{
		PlayAnimation(FadeLevel, 0.f, 1, EUMGSequencePlayMode::Reverse, 3.f);
	}
	else if (bIsFadingOut && GetAnimationCurrentTime(FadeLevel) <= 0.f)
	{
		Overlay_Base->SetVisibility(ESlateVisibility::Collapsed);
		bIsFadingOut = false;
	}
}

 

결과

좌측하단의 주황색 바 가 경험치 Exp와 바인드된 위젯입니다

 

 

 

 

저작자표시 비영리 변경금지 (새창열림)

'Unreal 프로젝트 다이어리 > 두번째 프로젝트' 카테고리의 다른 글

Unreal - 스탯창  (0) 2025.12.02
Unreal - 세이브 게임  (0) 2025.12.02
Unreal - 데미지 오버레이  (0) 2025.12.01
Unreal - 인벤토리(5-2) (UI 디테일 추가)  (0) 2025.11.29
Unreal - 인벤토리(5) ( 아이템 정보 )  (0) 2025.11.28
'Unreal 프로젝트 다이어리/두번째 프로젝트' 카테고리의 다른 글
  • Unreal - 스탯창
  • Unreal - 세이브 게임
  • Unreal - 데미지 오버레이
  • Unreal - 인벤토리(5-2) (UI 디테일 추가)
lucodev
lucodev
커피와 노트북 그리고 개발
  • lucodev
    루코 개발테이블
    lucodev
  • 전체
    오늘
    어제
    • 분류 전체보기 (210) N
      • Unreal 프로젝트 다이어리 (107) N
        • 첫번째 프로젝트 (73)
        • 두번째 프로젝트 (34) N
      • Unreal 팁 (8)
      • Unreal 디버깅 (8)
      • C++ 프로그래머스 (52)
        • Stack,Queue (7)
        • Hash (4)
        • Heap (2)
        • Sort (5)
        • Exhaustive search (5)
        • Greedy (2)
        • BFS , DFS (7)
        • Graph (2)
        • Dynamic Programming (1)
        • C++ Math (2)
        • 기타 문제 (14)
      • C++ 백준 (4)
      • C++ 팁 (1)
      • 개인 코테 & 스타디 <비공개> (29)
        • 코드 개인보관함 (9)
        • 코딩테스트+@ (11)
        • 알고리즘 스타디 (6)
        • 알고리즘 스타디 과제 (3)
        • 비공개 (0)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 링크

  • 공지사항

  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 태그

    언리얼 behavior tree
    언리얼
    언리얼 motionmatching
    언리얼 프로그래스바
    언리얼 파쿠르
    unreal inventory
    언리얼 ui
    언리얼 컷씬
    Unreal Parkour
    언리얼 behaviortree
    언리얼 parkour
    언리얼 시퀀스
    unreal 인벤토리
    언리얼 비헤이비어트리
    언리얼 모션매칭
    언리얼 인벤토리
    unreal 모션매칭
    unreal 시퀀스
    언리얼 상호작용
    unreal 파쿠르
  • hELLO· Designed By정상우.v4.10.3
lucodev
Unreal - 경험치, 레벨업 구현하기
상단으로

티스토리툴바