오늘 프로젝트를 진행하다가 자연스럽게 발생한 현상입니다.
테스트 레벨에서 진행할 때는 문제가 없던 기능이었는데 메인 레벨에 적용하면서 확인하니 UI 위에서 마우스 인풋액션의 메서드만 호출되는 버그가 발생하였습니다.
해당 과정을 해결하기 위해 가장 쉬운 키워드인 "언리얼 엔진 5 - UI 위에서 클릭할 경우 마우스 인풋액션 비활성화" 이런 식으로 검색을 했는데 다양한 해결 방법을 다 시도했지만 해결되지 않았습니다.
원인
UUserWidget을 사용할때 보통 CreateWidget을 통해서 생성한 후에 AddToViewport()를 선언해서 화면에 그리는 방식입니다.
HUDInstance = CreateWidget<UHUDWidget>(PlayerController, HUDClass);
HUDInstance->AddToViewport();
InventoryWidget = CreateWidget<UInventoryWidget>(Cast<APlayerController>(GetController()), InventoryWidgetClass);
InventoryWidget->AddToViewport();
InteractWidget = CreateWidget(Cast<APlayerController>(GetController()), InteractWidgetClass);
InteractWidget->AddToViewport();
여기서 문제가 발생하게 되었습니다.
AddToViewport() 메서드를 확인해 보면
void UUserWidget::AddToViewport(int32 ZOrder)
{
if (UGameViewportSubsystem* Subsystem = UGameViewportSubsystem::Get(GetWorld()))
{
FGameViewportWidgetSlot ViewportSlot;
if (bIsManagedByGameViewportSubsystem)
{
ViewportSlot = Subsystem->GetWidgetSlot(this);
}
ViewportSlot.ZOrder = ZOrder;
Subsystem->AddWidget(this, ViewportSlot);
}
}
파라미터 값으로 ZOrder를 입력하게 되어있습니다.
제가 발생한 에러 현상은 같은 0번 Viewport에 HUDInstnace, InteractWidget, InventoryWidget 이렇게 3개의 UI를 모두 그리게 되어서 발생하게 되었습니다.
해결방법
해결방법으로는 간단합니다.
HUDInstance = CreateWidget<UHUDWidget>(PlayerController, HUDClass);
HUDInstance->AddToViewport(0); // 가장 하위에 그려지는 UI
InventoryWidget = CreateWidget<UInventoryWidget>(Cast<APlayerController>(GetController()), InventoryWidgetClass);
InventoryWidget->AddToViewport(3); // 클릭 이벤트를 받기 위해서 가장 위에 그려지는 UI
InteractWidget = CreateWidget(Cast<APlayerController>(GetController()), InteractWidgetClass);
InteractWidget->AddToViewport(1); // 최하위 보단 높은 UI
다음처럼 AddToViewport를 할때 ZOrder값을 잘 정리하면 해결됩니다.
프로젝트의 구조가 커질수록 해당 부분에 민감하게 정리해두지 않으면 다양한 문제가 생길 수 있을 것 같습니다.
아래 사진을 보면 ZOrder에 대한 내용이 인식이 될것 같습니다.
감사합니다.