17. 스탯 UI 구현하기 - 1

2023. 10. 2. 14:58·[게임 개발] 개발 일지/RPG

서론

캐릭터의 스탯 UI를 구현하여 현재 스탯의 정보를 확인할 수 있고,
몬스터를 잡거나 퀘스트를 클리어하면 스탯 포인트를 지급하여 해당 포인트만큼 최대 체력이나 데미지를
증가시킬수 있게 하는것이 목표입니다.

 

스텟 위젯과 캐릭터 스텟사이의 관계를 어떻게 정할지, 몬스터가 죽었을 때 스탯 위젯의 스탯 포인트를
어떻게 증가시킬지가 관건인 듯 합니다.


위젯 블루프린트 구현

위젯을 다음과 같이 배치해 보았습니다. 최대 체력과 데미지를 나타내고 하단부에는 스탯 포인트가 나타나며
각 스탯 옆에 버튼을 배치해 해당 버튼을 누르면 스탯을 일정량만큼 증가시키도록 하였습니다.

 

위젯의 구성 목록입니다.

 


위젯 클래스 구현

스탯 텍스트 업데이트

void URPGStatWidget::UpdateMaxHp(float NewMaxHp)
{
	MaxHp = NewMaxHp;

	// MaxHp 값을 문자열로 변환하여 MaxHpText에 설정
	FString MaxHpString = FString(TEXT("%f"), MaxHp);
	MaxHpText->SetText(FText::FromString(MaxHpString));
}

텍스트의 값을 바꾸기 위해 다음과 같이 Update 함수를 만들어 주었습니다.
매개변수로 받은 최대 체력값을 FString 형으로 저장한 후 텍스트 박스에 넣기 위해 FText형으로 다시 변환하여
텍스트 박스의 내용을 수정해 주었습니다.

 

그러나 해당 부분에서 구현 오류가 발생하여 이에 대한 수정은 다음에 하고 우선 버튼 클릭으로 인한
스탯의 증가를 먼저 구현하기로 하였습니다.

 


스탯 증가 버튼 구현

DECLARE_MULTICAST_DELEGATE_OneParam(FOnMaxHpChangedDelegate, float /*MaxHp*/);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnDamageChangedDelegate, float /*Damage*/);

스탯 위젯의 해더파일에 다음과 같이 델리게이트 2개를 만들어 주었는데,

버튼을 눌러 스탯 위젯 내부의 최대 체력과 데미지의 값이 바뀐다면 해당 델리게이트를 브로드캐스팅 하여
이 델리게이트를 구독한 스탯 컴포넌트 역시 최대 체력과 데미지 값을 바꾸도록 구성하기 위함입니다.

 

void URPGStatWidget::IncreaseMaxHp(float Value)
{
	MaxHp += Value;
	UpdateMaxHp(MaxHp);

	OnMaxHpChanged.Broadcast(MaxHp);
}

스탯 증가 버튼을 눌렀을 때 호출될 함수를 구현해 주었습니다. 전달된 Value 값 만큼 최대 체력을 증가시키고
Update 함수를 호출해 위젯의 텍스트를 업데이트 합니다. 그리고 브로드캐스팅하여 해당 델리게이트를 구독한
스탯 컴포넌트 클래스의 MaxHp역시 변경되도록 합니다.

 

 버튼 클릭시 함수 호출되는 기능은 다음과 같이 위젯 블루프린트를 이용해서 On Clicked 이벤트 시
구현한 Increase 함수가 실행되도록 하였고 Value를 블루프린트 내부에서 정할 수 있도록 하였습니다.

 


캐릭터 클래스에 스탯 위젯 세팅

void ARPGCharacter::SetupWidget(URPGUserWidget* InUserWidget)
{

...

	// Stat 위젯
	URPGStatWidget* StatWidget = Cast<URPGStatWidget>(InUserWidget);
	if (StatWidget)
	{
		StatWidget->UpdateMaxHp(StatComp->GetMaxHp());
		StatWidget->UpdateDamage(StatComp->GetAttackDamage());

		StatWidget->OnMaxHpChanged.AddUObject(StatComp, &URPGCharacterStatComponent::SetMaxHp);
		StatWidget->OnDamageChanged.AddUObject(StatComp, &URPGCharacterStatComponent::SetDamage);
	}
}

캐릭터 클래스에서 다음과 같이 인터페이스 함수를 이용해 Stat 위젯에 대한 초기 설정을 해 주었습니다.

캐릭터 스탯 컴포넌트의 최대 체력과 데미지를 가져와 스탯 위젯의 최대 체력과 데미지를 설정해 줍니다.

 

이후 스탯 위젯의 최대 체력과 데미지 변경에 대한 델리게이트를 스탯 컴포넌트가 구독하게 하여서 변경이 일어나면
스탯 컴포넌트의 SetMaxHp와 SetDamage 함수가 호출되도록 하고, 이 함수를 통해서 스탯 컴포넌트의 델리게이트를
구독한 체력바 위젯 또한 업데이트 함수를 실행해 체력바 퍼센트에 대한 값이 변경될 수 있도록 하였습니다.

 

// RPGCharacterStatComponent.h

DECLARE_MULTICAST_DELEGATE_TwoParams(FOnHpChangedDelegate, float /*CurrentHp*/, float /*MaxHp*/);

그래서 다음과 같이 스탯 컴포넌트의 델리게이트를 기존의 OneParam으로 Current Hp만 보내줬던 것을 수정하여
TwoParams로 MaxHp까지 같이 전송해 주도록 하였습니다.

 

// RPGHpBarWidget.cpp

void URPGHpBarWidget::UpdateHpBar(float NewCurrentHp, float CurrentMaxHp)
{
	MaxHp = CurrentMaxHp;

	ensure(MaxHp > 0.0f);
	if (HpBar)
	{
		HpBar->SetPercent(NewCurrentHp / MaxHp);
	}
}

체력바 위젯의 업데이트 함수에서는 스탯 컴포넌트의 Hp값과 MaxHp값을 둘 다 전송받게 됩니다.


스탯 위젯의 최대체력 증가함수 -> 스탯 컴포넌트의 최대체력 수정 함수 -> 체력바 위젯의 업데이트 함수

의 과정을 통해서 해당 업데이트 함수가 실행되어도 변경된 MaxHp값에 대응하여 체력바의 퍼센트를  설정할 수 있게 되었습니다. 처음엔 이 과정을 넣지 않아서 체력바 퍼센트 설정이 이상하게 되어 맞아도 체력바가 줄지않는 버그가 있었는데
다음 사진과 같이 정상적으로 수정 되었습니다.

 

 


최대 체력 증가에 따른 현재 체력 증가

void URPGCharacterStatComponent::SetMaxHp(float NewMaxHp)
{
	float IncreaseHp = NewMaxHp - MaxHp;
	MaxHp = NewMaxHp;

	SetHp(CurrentHp + IncreaseHp);
}

최대 체력이 증가 하였는데 현재 체력이 그대로라면 체력 회복을 하기 전 까지는 의미가 없기 때문에

스탯 컴포넌트 클래스의 SetMaxHp 함수에서 다음과 같이 SetHp(CurrentHp+IncreaseHp)를 통해 최대 체력 증가 값 만큼 현재 체력에 더하도록 하였습니다.

 

사진과 같이 최대 체력 증가값에 따라 현재 체력이 늘어나는것을 확인할 수 있습니다.

 


구현 결과

다음과 같이 버튼을 눌렀을 때 스탯 컴포넌트의 스탯값이 실제로 변화하는 것 까지는 구현하였지만
아직 구현할 점이 많이 남아있습니다.

 

1. 텍스트가 제대로 표시 되지 않는 점 수정하기


2. 특정 버튼을 눌렀을 때 위젯이 나오게/들어가게 하기


3. 위젯이 나왔을때는 마우스 포인터가 나타나게 하고, 마우스 움직임에 따라 캐릭터의 시점이 돌아가지 않도록 하기

 

4. 스탯 포인트가 없을때는 버튼이 동작하지 않도록 하기

 

다음 포스팅에서는 해당 내용을 구현하여 돌아오도록 하겠습니다.

 

감사합니다!

저작자표시 (새창열림)

'[게임 개발] 개발 일지 > RPG' 카테고리의 다른 글

19. 퀘스트 시스템 - 데이터 테이블 구축  (0) 2023.10.05
18. 스탯 UI 구현하기 - 2  (0) 2023.10.03
16. 몬스터 리스폰 구현과 맵 적용  (0) 2023.09.30
15. 피격 파티클 추가, 행동에 사운드 추가  (0) 2023.09.30
14. 파티클과 사운드를 이용한 패링 연출 효과  (0) 2023.09.29
'[게임 개발] 개발 일지/RPG' 카테고리의 다른 글
  • 19. 퀘스트 시스템 - 데이터 테이블 구축
  • 18. 스탯 UI 구현하기 - 2
  • 16. 몬스터 리스폰 구현과 맵 적용
  • 15. 피격 파티클 추가, 행동에 사운드 추가
람팜팜~
람팜팜~
:)
  • 람팜팜~
    RumPumPum
    람팜팜~
  • 전체
    오늘
    어제
    • 전체 (123)
      • 🎵 일상 (2)
      • JAVA (5)
        • 김영한의 자바 입문 (3)
      • JavaScript (12)
      • ---------------------------.. (0)
      • [게임 개발] 포트폴리오 (2)
        • RPG (1)
        • 슈터-플랫포머 (1)
      • [게임 개발] 개발 일지 (28)
        • RPG (25)
        • TopDownProject (3)
      • [게임 개발] 언리얼엔진 공부 (9)
        • 이득우의 언리얼 프로그래밍 Part.1 (6)
        • 이득우의 언리얼 프로그래밍 Part.2 (1)
        • 개인 메모 (2)
      • [게임 개발] 알고리즘 공부 (60)
        • 프로그래머스 (8)
        • 백준 (52)
        • 개인 메모 (0)
      • [게임 개발] CPP 공부 (2)
        • 이것이 C++ 이다 (1)
        • Effective C++ (0)
        • Effective Modern C++ (0)
        • 홍정모 그래픽스 새싹코스 (1)
      • [게임 개발] CS 공부 (3)
  • 블로그 메뉴

    • 링크

      • Github
    • 공지사항

    • 인기 글

    • 태그

      누적합
      슬라이딩 윈도우
      문자열
      우선순위 큐
      역참조
      브루트포스
      dp
      context switching
      참조자
      스레드
      투포인터
      해시
      그리디
      메모리구조
      dfs
      프로세스
      데드락
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    람팜팜~
    17. 스탯 UI 구현하기 - 1
    상단으로

    티스토리툴바