[UE5] 안내창 UI 구현

연하·2024년 7월 11일
0

Trapper

목록 보기
19/32
post-thumbnail

어제까지 급하게 TGS 참가 심사용 빌드를 뽑느라 벨로그에 글 쓸 정신이 없었다. 잡히는대로 쳐내느라 뭘 했는지 정확히 기억은 안나지만, 튜토리얼 UI 구현정도는 한번 정리하고 다시 시작하는게 맞을 것 같아 열심히 써보려고 한다 :)

Widget 만들기

텍스트의 길이에 따라 크기가 조절되도록 하는게 관건이었는데, 간단할거라 생각했지만 여기서 꽤나 헤맸다.. 어쨌든 이것저것 찾아보고 해보면서 결론적으로는 잘(?) 구현하긴 했다. 다음에 만들땐 좀 덜 헤맬 수 있을까..

이번에는 HP Bar처럼 따로 위젯 파일을 나누지 않고 기존 Player HUD에 만들어주었다. Overlay 패널에 Image와 Vertical Box를 넣고, Vertical Box에는 Text 두개(타이틀, 본문)를 배치해주었다.

오버레이 패널 / 이미지 설정

본문의 내용에 따라 늘어나게 해야하므로 Size To Content를 체크해주었다. 이미지 크기는 본문에 한줄이 무조건 채워져 있다고 가정하고 X 300 / Y 70으로 지정해줬음!

테두리 상자 이미지 깨지지 않게 늘리기

테두리가 있는 상자 이미지다보니, 본문 크기에 맞춰 이미지가 늘어날 때 이미지가 깨지고 늘어나는 문제가 있었다.

Appearance의 Draw As와 Margin을 사용해주면 해결할 수 있다. Draw As를 Box로 선택해주면 마진으로 설정된 부분은 고정되고 나머지 부분은 Stratch되어 채워지는 것 같다.

이미지가 늘어나도 테두리가 훨씬 깔끔한걸 볼 수 있다.

Vertical Box / Text 설정

텍스트 주변에 상하좌우 여백이 있는게 훨씬 보기 좋을 것 같아 상하좌우 패딩을 20씩 주고, 꽉 채워진 정렬을 위해 Horizontal & Vertical Alignment를 모두 Fill로 설정해주었다.

-> 타이틀 텍스트 설정

-> 본문 텍스트 설정

사실.... 정확히 어떻게 기능하는지 잘 모르고 써서 뭐 하나만 잘못 건들이면 삐꾸가 나버린다 ㅎㅎ.. 나중에 공부해서 제대로 만들어봐야지..

그래도 일단 잘 동작하잖아요ㅠㅠ

Widget 연동

안내창에서 타이틀 텍스트와 본문 텍스트만 건들이면 되므로 이 두개만 변수로 만들어주고 C++과 연동해주었다.

// playerHUD.h

UPROPERTY(meta = (BindWidget), VisibleAnywhere, BlueprintReadOnly, Category = "Quest")
TObjectPtr<class UTextBlock> TitleText;

UPROPERTY(meta = (BindWidget), VisibleAnywhere, BlueprintReadOnly, Category = "Quest")
TObjectPtr<class UTextBlock> ContentsText;

void SetQuestText(FString InTitle, FString InContents);

// --------------------------------

// playerHUD.cpp

void UPlayerHUD::SetQuestText(FString InTitle, FString InContents)
{
	TitleText->SetText(FText::FromString(InTitle));
	ContentsText->SetText(FText::FromString(InContents));
}

playerHUD 클래스에 멤버변수와 함수를 선언해주고, 세팅하는 코드를 만들어주었다.

void AQuestManager::RequireSetQuestUI()
{
	if (!QuestList.IsValidIndex(CurrentQuestIndex)) return;

	FQuest CurrentQuest = QuestList[CurrentQuestIndex];

	if (CurrentQuest.GoalCount != 0)
	{
		FString Info = TEXT(" ") + FString::FromInt(CurrentQuest.Count) + TEXT("/") + FString::FromInt(CurrentQuest.GoalCount);
		CurrentQuest.Description += Info;
	}

	MyOwner->SetQuestUI(CurrentQuest.Title, CurrentQuest.Description);
}

퀘스트 매니저에서 현재 퀘스트 정보를 담아 GameMode에게 UI를 변경해달라는 요청을 보내면,

void ATrapperGameMode::SetQuestUI(FString Title, FString Contents)
{
	for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
	{
		ATrapperPlayerController* PlayerController = Cast<ATrapperPlayerController>(Iterator->Get());
		if (PlayerController)
		{
			PlayerController->MulticastRPCQuestSetting(Title, Contents);
		}
	}
}

게임모드에서 플레이어 컨트롤러에 접근해 멀티캐스트 함수를 호출해준다.

void ATrapperPlayerController::MulticastRPCQuestSetting_Implementation(const FString& InTitle, const FString& InDescription)
{
	if (IsLocalController() && PlayerHudRef)
	{
		PlayerHudRef->SetQuestText(InTitle, InDescription);
	}
}

그럼 RPC를 수신한 플레이어 컨트롤러에서 플레이어 허드에 접근해 퀘스트 텍스트를 세팅해주는 식!

정리하지 못했지만 그동안 했던 것들

퀘스트 위치에 이펙트 출력, 맵에 투명 벽과 트리거 박스 배치, 게임모드 버그 수정, 기획의 Q/A를 위한 편의성 기능 제공, 리스폰 UI 초기화, 함정을 사용할 때 아이템이 사용되게 하는 서버 처리, 클리어/게임오버 UI 및 처리, 제단 HP 등 게임의 완성도를 위해 이것저것 했던 것 같다.

이제 급한 빌드는 끝났으니, 해왔던 것처럼 하나씩 정리해가며 진행해야지 :)

0개의 댓글