상호작용 UI 중복 호출 문제

김여울·2026년 1월 6일

내일배움캠프

목록 보기
139/139

문제 1

문제

Door 생성자에서 InteractionWidget을 두 번 SetupAttachment 하고 있어서 양쪽 문에서 상호작용 UI가 두 개 나오는 문제가 생겼다.

원인

Door.cpp 생성자 부분:

InteractionWidget = CreateDefaultSubobject(TEXT("InteractionWidget"));
InteractionWidget->SetupAttachment(LeftDoorMesh);
InteractionWidget->SetupAttachment(RightDoorMesh);  // 여기가 문제!

InteractionWidget이 LeftDoorMesh와 RightDoorMesh 둘 다에 붙어있다.
이렇게 하면 두 번째 SetupAttachment가 첫 번째 걸 덮어쓰게 되는데, 더블 힌지 문의 경우 RightDoorMesh가 활성화되면 양쪽 문 모두 위젯을 가지게 된다.

그리고 BeginHighlight() 에서도 양쪽 문 메시와 위젯 모두 활성화하고 있다.

void ADoor::BeginHighlight()
{
    if (LeftDoorMesh)
    {
        LeftDoorMesh->SetRenderCustomDepth(true);
    }
    if (RightDoorMesh)
    {
        RightDoorMesh->SetRenderCustomDepth(true);
    }
    if (InteractionWidget)
    {
        InteractionWidget->SetVisibility(true);  // 위젯이 하나만 보여야 하는데
    }
}

해결

LeftDoorMesh에만 붙이기

InteractionWidget = CreateDefaultSubobject(TEXT("InteractionWidget"));
InteractionWidget->SetupAttachment(LeftDoorMesh);  // 왼쪽 문에만
// InteractionWidget->SetupAttachment(RightDoorMesh); 
InteractionWidget->SetWidgetSpace(EWidgetSpace::Screen);
InteractionWidget->SetVisibility(false);
InteractionWidget->SetCollisionEnabled(ECollisionEnabled::NoCollision);

문제 2

문제

캐릭터가 문을 감지해야 Highlight + 상호작용 UI 가 떠야하는데 Highlight가 감지하기도 전부터 계속 떠있다.

원인

Door의 BeginPlay에서 InteractionWidget을 꺼놓지 않았거나,
BeginPlay에서 위젯 초기화를 안 해서, 컴포넌트가 생성될 때 기본값으로 켜져 있을 수도 있다.

흐름을 정리해보면:

  • Door 생성자에서 InteractionWidget->SetVisibility(false)로 꺼놓기
  • 캐릭터의 LNInteractionDetectorComponent가 0.05초마다 DoTrace() 를 실행해서 가까운 오브젝트를 감지
  • 감지되면 BeginHighlight() 호출해서 위젯을 켜기
  • 멀어지면 EndHighlight() 호출해서 위젯을 끄기

해결 방법

Door.cpp의 BeginPlay 끝에 위젯 초기화 코드를 추가해줘:

void ADoor::BeginPlay()
{
    Super::BeginPlay();
    ApplySelectedSounds();
    
    // ... 기존 코드들 ...
    
    if (LeftDoorMesh)
    {
        LeftDoorMesh->SetRenderCustomDepth(false);
    }
    if (RightDoorMesh)
    {
        RightDoorMesh->SetRenderCustomDepth(false);
    }
    
    // 위젯 초기화 추가
    if (InteractionWidget)
    {
        InteractionWidget->SetVisibility(false);  // 처음엔 무조건 꺼놓기
    }
}

이젠 게임 시작할 때 모든 문의 상호작용 위젯이 꺼진 상태로 시작하고,
캐릭터가 가까이 가서 BeginHighlight() 가 호출될 때만 켜진다.

성공 ~

콜리전 설정의 차이점

QueryOnly vs NoCollision

QueryOnly는 충돌 검사만 활성화
NoCollision은 모든 충돌 기능이 꺼짐

QueryOnly

  • Line Trace, Sweep, Overlap 같은 쿼리에 반응함
  • 물리적인 충돌 반응은 없음 (물체가 뚫고 지나감)
  • (예) 아이템 근처에서 "Press E" 메시지 표시, 상호작용 감지
GemMesh->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
// Line Trace나 캐릭터의 Sweep으로 감지는 되지만, 물리적으론 통과

NoCollision

  • 모든 충돌이 비활성화됨
  • Line Trace, Sweep, Overlap 모두 감지 안 됨
  • 물리 엔진에서 아예 표현되지 않음
HammerMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
// 완전히 유령처럼 모든 걸 통과하고, 감지도 안 됨

예시

GemMesh->SetCollisionEnabled(ECollisionEnabled::QueryOnly);     // 감지는 되지만 물리 충돌은 없음 (줍기 가능)
HammerMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); // 완전히 투명, 아무것도 감지 안 됨
GemMesh는 캐릭터가 가까이 가면 감지되서 줍을 수 있고, HammerMesh는 완전히 꺼져서 아무 반응도 없음

QueryOnly 로 하기

0개의 댓글