[CommonUI] UI 위젯이 화면에 안 뜨는 문제

김여울·2025년 11월 25일

내일배움캠프

목록 보기
121/139
  • 컴파일 에러는 없음
  • LV_MainMenu에 GameMode / HUD Class 설정도 했음
  • 그치만 UI 위젯이 화면에 안 뜬다...

UI가 뜨려면 이행해야하는 것들

  1. LV_MainMenu → GameMode → HUD 생성

  2. ALNHUD::BeginPlay()
    RootLayoutClass 확인
    ULNPrimaryLayout 위젯 생성 + AddToViewport

  3. ULNPrimaryLayout::NativeConstruct()
    ULNUIManageSubsystem::SetRootLayout(this)
    ALNHUD::OnRootLayoutReady() 호출

  4. ALNHUD::OnRootLayoutReady()
    UIManager->ShowWidget(UI.Request.MainMenu)

  5. ULNUIManageSubsystem::ShowWidget()
    CachedWidgetMap 에서 Policy 찾기
    → LayerTag로 RootLayout->GetLayerWidget()
    → WidgetClass Load → Stack → AddWidget(..)

  6. MainMenu 위젯 화면에 표시

1. HUD가 실제로 생성되는지 확인

  1. LV_MainMenu 레벨에서 World Settings → GameMode Override
    UI용 GameMode BP 가 들어가 있는지 확인

  2. 그 GameMode BP 의 Details → HUD Class
    BP_LNHUD 가 들어가 있는지 확인

  3. ALNHUD::BeginPlay()에 로그 추가하기

UE_LOG(LogTemp, Display, TEXT("ALNHUD: RootLayout 인스턴스 생성 완료"));

✅ Output Log에

  • 로그가 안 뜨면 → GameMode/HUDClass 설정이 잘못된 거라 HUD 자체가 안 만들어진 것
  • 로그가 뜬다면 → HUD는 정상, 다음 단계로 넘어가기

2. RootLayoutClass 세팅 확인

BeginPlay()

if (!RootLayoutClass)
{
    UE_LOG(LogTemp, Error,
           TEXT("ALNHUD: RootLayoutClass가 설정되지 않았습니다. (BP_LNHUD에서 설정 필요"));
    return;
}

✅ Output Log에 이 에러 보이면

  • BP_LNHUD 열어서 Class Defaults → RootLayoutClass
    WBP_PrimaryLayout 할당하기
  • 이게 비어 있으면 RootLayout을 안 만들고 바로 return 해버려서 당연히 UI 안 나옴

3. PrimaryLayout이 Subsystem에 등록되는지 확인

ULNPrimaryLayout::NativeConstruct()

if (UGameInstance* GI = GetGameInstance())
{
    if (ULNUIManageSubsystem* UISubsystem = GI->GetSubsystem<ULNUIManageSubsystem>())
    {
        UISubsystem->SetRootLayout(this);
    }
}

// 그리고 그 뒤에 HUD->OnRootLayoutReady() 호출
UE_LOG(LogTemp, Log, TEXT("LNPrimaryLayout: NativeConstruct 실행됨"));	// 추가

✅ Output Log에

  • 안 뜨면WBP_PrimaryLayout의 부모 클래스가 ULNPrimaryLayout 이 맞는지,
    레벨에서 정말 그 위젯이 생성됐는지 다시 확인하기
    (부모가 일반 UserWidget이면 NativeConstruct 오버라이드 안 불림)
  • 뜬다면 → PrimaryLayout은 제대로 초기화 중, 다음 단계로 이동

4. OnRootLayoutReady 가 실제로 불리는지 확인

NativeConstruct() 에서 HUD 찾은 뒤:

if (APlayerController* PC = GetOwningPlayer())
{
    if (ALNHUD* HUD = PC->GetHUD<ALNHUD>())
    {
        UE_LOG(LogTemp, Log, TEXT("LNPrimaryLayout: HUD 찾음, OnRootLayoutReady 호출"));
        HUD->OnRootLayoutReady();
    }
}

그리고 ALNHUD::OnRootLayoutReady() 처음 줄에:

UE_LOG(LogTemp, Log, TEXT("ALNHUD: OnRootLayoutReady 호출됨"));

✅ Output Log에

  • 둘 다 뜬다 → HUD까지 호출 OK, 그 다음은 Subsystem/Tag/DataAsset 문제
  • PrimaryLayout 로그는 뜨는데 HUD 로그가 안 뜬다
    GetHUD<ALNHUD>() 가 null 이거나 HUDClass 가 다른 클래스로 세팅돼 있을 가능성 (추측)

5. UIManageSubsystem 이 DataAsset을 제대로 읽는지 확인

ULNUIManageSubsystem::Initialize()

UE_LOG(LogTemp, Log,
       TEXT("UIManageSubsystem: %d개의 UI 정책(UI 맵) 로드됨."),
       CachedWidgetMap.Num());

그리고 Config 경로가 잘못됐을 때:

UE_LOG(LogTemp, Error,
       TEXT("UIManageSubsystem: UIMapDataAssetPath is invalid. DefaultGame.ini 설정 확인 필요"));

✅ Output Log에 UIManageSubsystem 필터로 확인

  • "Path is invalid"DefaultGame.ini
    [/Script/OurLongNight.LNUIManageSubsystem]
    LNMapDataAssetPath="/Game/경로/DA_LNMap.DA_LNMap"
    이게 제대로 안 써져있다는 뜻
  • 개수 로그가 뜨는데 0개의 UI 정책 이라고 나오면
    → DataAsset은 불러왔는데 안에 WidgetMap이 비어있다는 뜻 (DA에 MainMenu 항목이 없는 것)

6. ShowWidget 에서 어디서 막히는지 로그로 확인

ShowWidget 안에 이미 Warning 로그들 있음

  • RootLayout 없음
  • UI Policy에 등록된 태그 없음
  • LayerTag invalid
  • 레이어 스택 없음
  • WidgetClass 미설정
  • 클래스를 로드할 수 없음

Output Log에서 ShowWidget 으로 검색하기

정확히 어느 단계에서 null 이 나오는지

흔한 경우:

  1. DA_LNMapWidgetMap
  • Key: UI.Request.MainMenu
  • Value:
    • WidgetClass = WBP_MainMenu (부모: UCommonActivatableWidget)
    • TargetLayer = UI.Layer.Main
    → 이 셋이 제대로 안 맞아 있는 경우
  1. WBP_PrimaryLayout 안에서 레이어 등록(RegisterLayer) 이 안 되어 있는 경우
    GetLayerWidget 이 null 반환 → “레이어 스택 없음” 로그

7. 로그 체크

Output Log 열고 검색어 순서대로 보기:

  • ALNHUD: RootLayout 인스턴스 생성
  • LNPrimaryLayout: NativeConstruct
  • ALNHUD: OnRootLayoutReady
  • UIManageSubsystem
  • ShowWidget

문제

  1. Subsystem Initialize 단계
    • UIMapDataAssetPath 가 Config에서 제대로 안 들어와서
      IsValid() 가 실패함
    • 그래서 DataAsset을 전혀 못 로드했고, CachedWidgetMap 도 비어 있음
  2. 그 뒤 흐름
    • HUD는 잘 만들어지고 (RootLayout 인스턴스 생성 완료)
    • PrimaryLayout도 Subsystem에 잘 등록됨 (RootLayout 등록 완료)
  3. 위젯을 띄우려 할 때
    - ShowWidget(UI.Request.ShowHUD) 를 호출했지만
    - CachedWidgetMap.Find(RequestTag) 에서 아무것도 못 찾음 → UI Policy에 등록된 태그가 없음 경고

고치기

  1. DefaultGame.ini – LNMapDataAssetPath 고치기

  2. LNMapDataAsset 안에 UI.Request.ShowHUD 항목이 비어 있거나 아예 없음
    DA_LNMapDataAsset 안에 HUD 태그 매핑 추가

  3. RootLayout(PrimaryLayout)에 Layer가 등록

    • Event Construct
      → RegisterLayer(UI.Layer.Main , WB_MainLayer_Stack)
      → RegisterLayer(UI.Layer.Dialog, WB_DialogLayer_Stack)
      → RegisterLayer(UI.Layer.Overlay, WB_OverlayLayer_Stack)
      → RegisterLayer(UI.Layer.HUD , WB_HUDLayer_Stack)

  1. DA_LNMapDataAsset 의 조건이 정확히
    MainMenu 띄우려면 DA가 이렇게 돼 있어야 한다:

    KeyWidgetClassLayer
    UI.Request.MainMenuWBP_MainMenuUI.Layer.Main

    MainMenu 맵에서는 MainMenu만 띄우면 됨

5. HUD 쪽 로직이 MainMenu를 안 띄우고 HUD 를 띄우고 있는지 확인
기존 코드

if (CurrentLevelName.Contains("Frontend"))
{
    UIManager->ShowWidget(FGameplayTag::RequestGameplayTag(TEXT("UI.Request.MainMenu")));
}
else
{
    UIManager->ShowWidget(FGameplayTag::RequestGameplayTag(TEXT("UI.Request.ShowHUD")));
}

지금 LV_MainMenu 레벨 이름이 Frontend를 포함함?
→ 레벨 이름이 LV_MainMenu 라서 Frontend 라는 글자가 없어서 ShowHUD 를 띄우려고 하고 있음
그러면 HUD는 없어 → MainMenu도 안 뜸 → 아무것도 안 뜸

// 방법 1 - 레벨 이름 체크 변경
if (CurrentLevelName.Contains("MainMenu"))

// 방법 2 - 그냥 무조건 MainMenu 띄우기
UIManager->ShowWidget(FGameplayTag::RequestGameplayTag(TEXT("UI.Request.MainMenu")));

// ⭐ 방법 3 - Tag 사용하기 ⭐
UIManager->ShowWidget(LNGameplayTags::UI_Request_MainMenu);

다 하고 라이더 껐다 다시 열면 됨!!!
그치만 위젯 위치가 너무 구리다...

0개의 댓글