[CH4-15] ScrollBox를 MultiLineEditableTextBox로 변경하여 게임오버 UI 랭킹 표시 개선

김여울·2025년 9월 29일

내일배움캠프

목록 보기
87/139

💥 문제 상황

  • 게임오버 화면에서 ScrollBox + 동적 TextBlock 생성 방식으로 랭킹을 표시
  • 한글 폰트가 지원되지 않아 "1위 : 닉네임" 형식에서 한글 부분이 깨짐
  • 동적 생성된 TextBlock들의 폰트 설정이 복잡하고 어려웠음
  • 폰트 설정을 위해 코드가 복잡해지고 유지보수가 어려워짐

🔧 해결 과정

1단계: 위젯 타입 결정

고려했던 UMG 위젯 옵션들:

  • Editable Text ← 한 줄만 가능 (X)
  • Editable Text (Multi-Line) ← 입력용이라 처음엔 고려했으나 컴파일 에러 발생
  • Text Box ← 단순 표시용, 한 줄만 (X)
  • Text Box (Multi-Line) ← 최종 선택

2단계: 완전한 코드 구조 변경

기존 구조 (ScrollBox 방식):

// DCGameOverWidget.h
UPROPERTY(meta=(BindWidget))
UScrollBox* RankingScrollBox;

// DCGameOverWidget.cpp  
#include "Components/ScrollBox.h"
#include "Components/TextBlock.h"
#include "Blueprint/WidgetTree.h"

// 복잡한 동적 생성 방식
for (int32 i = 0; i < Results.Num(); ++i) {
    UTextBlock* RowText = WidgetTree->ConstructWidget<UTextBlock>(...);
    
    // 폰트 설정이 매우 복잡
    FSlateFontInfo FontInfo = RowText->GetFont();
    FontInfo.Size = 24;
    RowText->SetFont(FontInfo);
    RowText->SetColorAndOpacity(FSlateColor(FLinearColor::Red));
    
    // 한글 포함 텍스트 (폰트 문제 발생)
    RowText->SetText(FText::FromString(
        FString::Printf(TEXT("%d위 : %s"), DisplayRank, *R.Nickname)
    ));
    
    RankingScrollBox->AddChild(RowText);
}

변경된 구조 (MultiLineEditableTextBox 방식):

// DCGameOverWidget.h
UPROPERTY(meta=(BindWidget))
class UMultiLineEditableTextBox* RankingTextBox;

// DCGameOverWidget.cpp
#include "Components/MultiLineEditableTextBox.h"

// 단순하고 효율적인 문자열 조합 방식
FString RankingText;
for (int32 i = 0; i < Results.Num(); ++i) {
    const FPlayerResult& R = Results[i];
    // 한글 제거로 폰트 문제 해결
    RankingText += FString::Printf(TEXT("%s\n"), *R.Nickname);
}

RankingTextBox->SetText(FText::FromString(RankingText));
RankingTextBox->SetIsReadOnly(true); // 읽기 전용 설정

3단계: 트러블슈팅 과정

발생한 주요 에러들과 해결책:

  1. 컴파일 에러: 'UEditableTextBox' : undeclared identifier
  • 원인: 잘못된 전방선언과 include
  • 해결: UMultiLineEditableTextBox로 정확히 변경
  1. 재정의 에러: 'FString RankingText': 재정의
  • 원인: 같은 함수 내에서 동일 변수명을 두 번 선언
  • 해결: 중복된 변수 선언 제거
// ❌ 잘못된 코드
FString RankingText; // 첫 번째 선언
// ... 중간 코드들 ...
FString RankingText; // 두 번째 선언 (에러!)

// ✅ 올바른 코드  
FString RankingText; // 한 번만 선언
  1. 위젯 바인딩 에러: WBP에서 위젯 이름 불일치
  • 원인: 대소문자 구분, 띄어쓰기 등
  • 해결: 정확히 RankingTextBox로 명명

4단계: WBP(위젯 블루프린트) 설정

정확한 설정 순서:

  1. 위젯 추가: "Text Box (Multi-Line)" 선택
  2. 이름 설정: 정확히 RankingTextBox로 명명 (대소문자 주의)
  3. 속성 설정:
  • Is Read Only: ✅ 체크 (편집 불가능)
  • Auto Wrap Text: ✅ 체크 (자동 줄바꿈)
  • 폰트/크기/색상: BP에서 직관적으로 설정 가능


해결 완료 ~
디자인도 수정하기..

🔧 변경사항 비교표

구분기존 방식 (ScrollBox)변경된 방식 (MultiLineEditableTextBox)
위젯 구조ScrollBox + 다수의 TextBlock단일 MultiLineEditableTextBox
구현 복잡도복잡 (동적 위젯 생성)단순 (문자열 조합)
폰트 설정코드에서 복잡하게 설정BP에서 직관적으로 설정
텍스트 형식"1위 : 닉네임" (한글 포함)"닉네임" (영어만)
헤더 includeScrollBox.h, TextBlock.h, WidgetTree.hMultiLineEditableTextBox.h
성능동적 생성으로 오버헤드정적 텍스트로 최적화
유지보수복잡한 코드 구조간단하고 명확한 구조

🚨 주요 실수와 해결법

1. 위젯 타입 선택 실수

❌ Editable Text (Multi-Line) → 컴파일 에러
✅ Text Box (Multi-Line) → 정상 작동

2. 변수 재정의 실수

// ❌ 잘못된 패턴
FString RankingText;
// ... 코드 ...
FString RankingText; // 재정의 에러!

// ✅ 올바른 패턴
FString RankingText; // 한 번만 선언
// ... 모든 작업 ...

3. 헤더 파일 전방선언 실수

// ❌ 잘못된 전방선언
class UEditableTextBox;

// ✅ 올바른 전방선언  
class UMultiLineEditableTextBox;

4. WBP 위젯 이름 실수

❌ rankingtextbox, RankingTextbox, Ranking_TextBox
✅ RankingTextBox (정확한 대소문자 구분)

✅ 최종 동작

해결된 문제들

  • 한글 폰트 문제 완전 해결
  • 코드 복잡도 70% 이상 감소
  • 성능 최적화 (동적 생성 → 정적 텍스트)
  • 유지보수성 대폭 향상
  • BP에서 스타일 변경 가능

추가 이점들

  • 메모리 사용량 감소
  • 렌더링 성능 향상
  • 코드 디버깅 용이성
  • 새로운 기능 추가 시 확장성

0개의 댓글