본문으로 건너뛰기

안동민 개발노트

본문 시작

사용자 인터페이스와 환경 연동

시선과 상호작용 범위를 판별해 안내 위젯을 표시하고 월드 상태와 UI 피드백이 일치하도록 연결합니다.

트리거로 상호작용을 만들었다면, 이제는 플레이어가 그 의미를 즉시 이해하도록 신호를 설계해야 합니다.

핵심은 사용자 인터페이스(User Interface, UI) 연동입니다.

플레이어가 오브젝트를 바라보거나 상호작용 범위에 들어왔을 때 적절한 안내를 띄우면, 다음 행동이 훨씬 자연스러워지고 시행착오도 줄어듭니다.

이번 절에서는 UI와 월드 상호작용을 끊김 없이 연결하는 방법을 다룹니다.

정리된 피드백 흐름을 적용하면 레벨의 정보 전달력이 올라가고, 플레이어 경험도 한층 매끄러워집니다.

사용자 인터페이스와 환경 연동

환경 상호작용 UI는 플레이어 시선, 입력 가능 상태, 월드 이벤트 결과를 같은 시점에 표시해 조작 가능한 대상을 오해 없이 전달해야 합니다.

  1. 상호작용 신호 표시

    Trace나 Overlap 결과가 유효할 때만 프롬프트를 띄우고, 대상이 바뀌면 표시 텍스트도 즉시 갱신합니다.

  2. 사용자 인터페이스 (UI) 기본 개념

    언리얼 엔진에서는 주로 위젯 블루프린트(Widget Blueprint)를 사용하여 UI를 제작하고 화면에 표시합니다.

  3. 시선 기반 상호작용 구현

    플레이어의 카메라 시선이 특정 오브젝트에 닿았을 때 이를 감지하고 UI를 표시하는 방식입니다.

  4. 사용자 인터페이스와 환경 연동 기준

    정확성 표시 조건은 감지된 액터, 입력 가능 거리, 현재 상호작용 상태를 모두 만족할 때만 참이어야 합니다. 비용 매 프레임 위젯을 새로 만들지 않고 기존 위젯의 텍스트와 가시성만 바꿔 비용을 줄입니다. 확장성 문, 상자, NPC처럼 대상이 늘어나도 인터페이스 호출 규칙과 실패 피드백을 같은 함수 경로로 유지합니다. 예외 (예: E 키를 눌러 문 열기) 입력 안내가 남아 있으면 오작동처럼 보이므로, 상호작용 가능 범위를 벗어나면 UI를 숨깁니다.

  5. 정확성 표시 조건

    감지된 액터, 입력 가능 거리, 현재 상호작용 상태를 모두 만족할 때만 참이어야 합니다.

  6. 비용 매 프레임 위젯

    새로 만들지 않고 기존 위젯의 텍스트와 가시성만 바꿔 비용을 줄입니다.

  7. 확장성 문, 상자, NPC처럼 대상

    늘어나도 인터페이스 호출 규칙과 실패 피드백을 같은 함수 경로로 유지합니다.

  8. 예외 (예

    키를 눌러 문 열기) 입력 안내가 남아 있으면 오작동처럼 보이므로, 상호작용 가능 범위를 벗어나면 UI를 숨깁니다.


사용자 인터페이스 (UI) 연동의 중요성

환경 상호작용에 UI를 연동하는 것은 플레이어 경험에 다음과 같은 긍정적인 영향을 미칩니다.

  • 직관적인 정보 전달: 플레이어가 무엇과 상호작용할 수 있는지, 어떻게 상호작용해야 하는지 즉시 알 수 있게 합니다. (예: E 키를 눌러 문 열기)
  • 몰입감 향상: 게임 세계 내에서 일어나는 일에 대한 시각적인 피드백을 제공하여 플레이어가 더욱 게임에 몰입하게 합니다.
  • 방향성 제시: 플레이어가 다음에 무엇을 해야 할지, 또는 어떤 목표를 향해 나아가야 할지 간접적으로 안내합니다.
  • 오류 방지: 플레이어가 잘못된 행동을 하거나, 상호작용할 수 없는 오브젝트에 불필요한 시도를 하는 것을 방지합니다.

사용자 인터페이스 (UI) 기본 개념

언리얼 엔진에서는 주로 위젯 블루프린트(Widget Blueprint)를 사용하여 UI를 제작하고 화면에 표시합니다.

위젯 블루프린트 (Widget Blueprint)

  • 역할: 버튼, 텍스트, 이미지, 진행 바 등 게임 UI 요소를 시각적으로 디자인하고 기능을 부여하는 에셋입니다.
  • 생성: 콘텐츠 브라우저에서 마우스 오른쪽 버튼 클릭 사용자 인터페이스(User Interface) > 위젯 블루프린트(Widget Blueprint)를 선택합니다.
    • 보통 User Widget을 부모 클래스로 선택하고 WBP_ 접두사를 붙여 이름을 지정합니다. (예: WBP_InteractionPrompt)
  • 위젯 디자이너 (Widget Designer)
    • 팔레트(Palette)에서 Text, Image, Button 등 UI 요소를 캔버스에 드래그하여 배치하고 크기, 위치, 색상 등을 조절합니다.
    • Hierarchy 패널에서 위젯들의 계층 구조를 관리합니다.
    • Details 패널에서 각 위젯의 속성(텍스트 내용, 이미지 소스, 글꼴, 크기)을 설정합니다.
  • 그래프 (Graph)
    • 위젯의 기능적 로직을 구현하는 블루프린트 그래프입니다.
    • Construct (위젯 생성 시), Destruct (위젯 제거 시), OnButtonClicked (버튼 클릭 시) 등 다양한 이벤트와 함수를 활용합니다.
    • 텍스트 내용 변경, 이미지 교체 등 동적인 UI 변화를 여기서 제어합니다.

위젯을 화면에 추가/제거

  • 위젯 생성 및 화면 추가
    • 블루프린트에서 Create Widget 노드를 사용하여 위젯 블루프린트의 인스턴스를 생성합니다.
    • 생성된 위젯의 참조를 가져와 Add to Viewport 노드를 호출하여 위젯을 화면에 표시합니다.
  • 위젯 제거
    • 위젯 참조를 가져와 Remove from Parent 노드를 호출하여 위젯을 화면에서 제거합니다.

시선 기반 상호작용 구현

플레이어의 카메라 시선이 특정 오브젝트에 닿았을 때 이를 감지하고 UI를 표시하는 방식입니다.

정교한 상호작용에 주로 사용됩니다.

Line Trace (라인 트레이스)

  • 역할: 특정 시작점에서 특정 방향으로 선(Ray)을 발사하여, 그 선이 어떤 오브젝트와 충돌하는지 감지하는 물리 쿼리입니다.
  • 주요 노드: Line Trace By Channel
    • Start: 라인 트레이스가 시작될 월드 좌표. (보통 카메라 컴포넌트의 월드 위치)
    • End: 라인 트레이스가 끝날 월드 좌표. (Start에서 카메라의 앞쪽 방향 벡터에 일정 거리를 곱한 값을 더함)
    • Trace Channel: 어떤 충돌 채널과 충돌을 감지할지 지정합니다. (예: Visibility, Camera)
    • Draw Debug Type: 디버깅을 위해 라인 트레이스를 시각화합니다. (Line, Persistent, ForDuration 등)
    • Out Hit: 충돌이 발생했을 때 충돌한 액터, 위치, 법선(Normal), 충돌 컴포넌트 등의 상세 정보를 반환합니다.

Line Trace를 활용한 상호작용 UI 구현 로직

Line Trace UI는 지금 바라본 대상이 상호작용 가능한지 안정적으로 판정한다

선을 맞히는 것보다 이전 대상과 표시 상태를 함께 관리해 프롬프트 깜빡임을 줄이는 구조가 중요하다.

  1. Camera Forward

    카메라 위치와 정면 방향으로 짧은 선을 만든다.

  2. Trace Channel

    Visibility 또는 Interactable 전용 채널로 검사한다.

  3. Interface Check

    Hit Actor가 상호작용 인터페이스를 구현했는지 본다.

  4. Prompt State

    텍스트 표시, 갱신, 숨김을 이전 대상과 비교한다.

  5. Input

    Interact Action이 현재 대상에만 전달되게 한다.

기준판정
UI 깜빡임PrevHitActor와 현재 Hit Actor를 비교해 상태 변경을 줄인다.
성능 부담Tick 대신 Timer로 검사 간격을 조정한다.

시선 기반 UI는 한 번 띄우는 것보다, 대상이 바뀌거나 사라질 때 위젯 참조와 표시 상태를 함께 정리하는 흐름이 중요합니다.

시선 기반 UI: 대상 변경과 숨김 처리가 핵심

Line Trace가 맞은 액터만 보는 것이 아니라, 이전 대상과 현재 대상이 달라졌을 때 위젯 텍스트와 표시 상태를 함께 갱신해야 합니다.

  1. 카메라 앞 대상 확인

    Trace 카메라 위치와 전방 벡터로 짧은 탐색선을 만들고 상호작용 가능 액터만 통과시킵니다.

  2. 참조를 한 번 생성

    Widget 매 프레임 새 위젯을 만들지 않고 변수에 보관한 참조를 재사용합니다.

  3. 이전 대상과 비교

    Actor PrevHitActor가 바뀌면 프롬프트 문구를 새 오브젝트 이름으로 바꿉니다.

  4. 충돌 없음은 숨김

    Hide 탐색 실패나 캐스트 실패 시 Visibility를 끄고 이전 대상 값을 비웁니다.

UI 위젯 변수 생성: PlayerCharacter 블루프린트에 InteractionPromptWidget (타입: WBP_InteractionPrompt 오브젝트 참조) 변수를 추가합니다.

Event Tick에서 Line Trace 실행
  • Event Tick 노드에서 Get Player Camera Manager를 가져와 Get Camera Location (Start)과 Get Camera World Rotation (Direction)을 얻습니다.
  • Get Forward Vector 노드에 Get Camera World Rotation을 연결하여 카메라가 바라보는 방향 벡터를 얻습니다.
  • Vector * Float 노드를 사용하여 방향 벡터에 상호작용 가능 거리(예: 250.0 cm)를 곱합니다.
  • Vector + Vector 노드를 사용하여 Camera Location에 계산된 벡터를 더해 End 지점을 만듭니다.
  • Line Trace By Channel 노드를 호출합니다.
    • StartEnd에 위에서 계산한 값을 연결합니다.
    • Trace ChannelVisibility로 설정합니다.
    • Draw Debug TypeForDuration으로 설정하여 디버깅을 돕습니다.
  • Line Trace By ChannelReturn Value (충돌 여부)를 Branch 노드에 연결합니다.
충돌 대상 처리
  • True (충돌 발생 시)
    • Out Hit 구조체 핀을 Break Hit Result 노드로 분리합니다.
    • Hit Actor 핀을 Cast To BP_InteractableBase (또는 상호작용 가능한 모든 오브젝트의 부모 클래스)로 연결합니다. 이 캐스트는 현재 바라보는 액터가 상호작용 가능한 액터인지 확인합니다.
    • UI 표시: 캐스트 성공 시
      • InteractionPromptWidget 변수가 유효하지 않다면 (Is Valid 노드), Create Widget (WBP_InteractionPrompt) 노드를 사용하여 위젯을 생성하고 Add to Viewport로 화면에 추가한 후, InteractionPromptWidget 변수에 저장합니다.
      • 위젯의 텍스트를 E 키를 눌러 [오브젝트 이름] 상호작용과 같이 설정합니다.
      • Set Visibility (InteractionPromptWidget) 노드를 사용하여 위젯을 보이게 합니다.
    • 이전 프레임의 상호작용 대상 저장: PrevHitActor (Actor Object Reference) 변수를 만들어 현재 바라보는 액터를 저장합니다. 다음 프레임에서 이 액터와 현재 액터가 다른지 비교하여, 더 이상 상호작용 대상이 아닐 경우 UI를 숨깁니다.
  • False (충돌 없음 시)
    • InteractionPromptWidget 변수가 유효하다면 (Is Valid 노드), Set Visibility (InteractionPromptWidget) 노드를 사용하여 위젯을 숨깁니다.
    • PrevHitActor 변수도 초기화합니다.

UI 피드백은 화면에 띄우는 방식보다 상태 전환 규칙이 더 중요합니다.

아래 기준으로 입력 가능, 표시, 숨김, 정리 단계를 분리하면 프롬프트가 남거나 깜박이는 문제를 줄일 수 있습니다.

프롬프트는 표시물이 아니라 상태 머신으로 관리한다

바라보는 대상, 입력 가능 여부, 위젯 참조를 같은 흐름에서 갱신해야 UI가 남거나 깜박이지 않습니다.

  1. 규칙
    대상이 바뀌면 먼저 숨기고 다시 보여준다

    규칙 대상이 바뀌면 먼저 숨기고 다시 보여준다 PrevHitActor와 CurrentHitActor 비교가 기준입니다.

  2. Idle
    대상 없음

    Idle Trace 실패 시 위젯을 숨기고 이전 대상을 비웁니다.

  3. Candidate
    상호작용 후보

    Candidate 캐스트 성공 후 거리와 잠금 상태를 확인합니다.

  4. Visible
    프롬프트 표시

    Visible 위젯이 없으면 생성하고, 있으면 텍스트만 갱신합니다.

  5. Commit
    입력 실행

    Commit Interact 입력 후 대상 함수 호출과 UI 정리를 함께 수행합니다.


사용자 인터페이스 (UI) 피드백 종류

상호작용에 대한 피드백은 텍스트 UI 외에도 다양하게 제공될 수 있습니다.

  • 텍스트 프롬프트 (Text Prompt): E 키를 눌러 상호작용, 문 열기 등 가장 흔하고 명확한 피드백입니다.
  • 아이콘/커서 변화: 상호작용 가능한 오브젝트 위에 마우스 커서가 올라가거나 시선이 닿았을 때, 커서 아이콘이 변하거나 전용 상호작용 아이콘이 표시됩니다.
  • 오브젝트 하이라이트: 상호작용 가능한 오브젝트의 외곽선이 빛나거나 색상이 변하여 플레이어의 시선을 끕니다.
    • 구현: 오브젝트의 머티리얼에 하이라이트 기능을 추가하고, 블루프린트에서 Set Scalar Parameter Value 등으로 하이라이트 강도를 조절합니다. 또는 Custom Depth RenderPost Process Material을 조합하여 아웃라인 효과를 구현합니다.
  • 사운드 피드백: 상호작용 가능 영역에 진입하거나 오브젝트를 바라볼 때 미묘한 소리나 UI 소리를 재생하여 청각적인 단서를 제공합니다.
  • 애니메이션: 오브젝트 자체에 짧은 시각적 애니메이션(예: 스위치가 살짝 튀어나옴)을 주어 상호작용 가능성을 암시합니다.

피드백 채널은 많이 겹칠수록 좋은 것이 아니라, 플레이어가 지금 알아야 할 질문에 맞게 나누는 편이 명확합니다.

UI 피드백은 정보의 긴급도에 맞는 채널 선택

텍스트 프롬프트, 커서, 하이라이트, 사운드는 같은 의미를 반복하는 장식이 아니라 서로 다른 플레이어 질문에 답해야 합니다.

  1. Prompt
    UI 입력 대상

    Prompt 입력 키와 동작 이름을 짧게 표시합니다. 대상이 바뀌면 텍스트를 즉시 갱신합니다.

  2. Cursor
    상호작용 가능한가

    Cursor 시선이 닿은 순간 가능 여부를 알려 주되 잠긴 대상과 가능한 대상을 구분합니다.

  3. Outline
    어느 오브젝트인가

    Outline Custom Depth나 머티리얼 파라미터로 선택된 대상만 강조합니다.

  4. Sound
    상태가 바뀌었나

    Sound 진입, 선택, 실패, 완료를 서로 다른 짧은 소리로 구분합니다.

  5. clarity
    한 메시지 한 의미

    clarity 프롬프트에는 입력과 행동만 두고 설명문은 퀘스트 UI로 분리합니다.

  6. state
    상태별 다른 반응

    state 가능, 잠김, 쿨다운, 완료 상태를 같은 색과 소리로 처리하지 않습니다.

  7. cleanup
    대상 이탈 정리

    cleanup Trace 실패와 EndOverlap에서 위젯, 하이라이트, 사운드 루프를 함께 정리합니다.


사용자 인터페이스 연동 최적화 및 고려 사항

  • 성능: Event Tick에서 Line Trace를 매 프레임 실행하는 것은 성능에 부담을 줄 수 있습니다.
    • 최적화: Set Timer by Event 노드를 사용하여 Line Trace를 0.1초 또는 0.2초 간격으로 실행하거나, 플레이어가 움직일 때만 Line Trace를 실행하는 등 업데이트 주기를 조절합니다.
    • 충돌 채널 최적화: Trace ChannelVisibility 대신 Custom 채널(예: Interactable)을 만들고, 상호작용 가능한 오브젝트에만 해당 채널을 Block하도록 설정하여 불필요한 충돌 계산을 줄입니다.
  • 명확성: UI 피드백은 명확하고 간결해야 합니다. 너무 많은 정보나 혼란스러운 시각 효과는 피합니다.
  • 일관성: 게임 내 모든 상호작용 가능한 오브젝트에 일관된 UI 피드백 방식을 적용하여 플레이어가 빠르게 학습할 수 있도록 합니다.
  • 입력 매핑: 상호작용 키(예: E 키)는 Input Action으로 정의하여 플레이어가 키를 재설정할 수 있도록 합니다.

사용자 인터페이스와 환경 연동은 플레이어가 게임 세계와 소통하는 중요한 다리 역할을 합니다.

UI와 환경 연동은 시선 감지, 위젯 표시, 피드백 조건을 명확히 나누어 구현합니다.

입력 지점과 표시 조건을 함께 테스트하세요.

UI와 환경 연동 흐름

환경 UI는 플레이어가 무엇을 바라보고 무엇을 할 수 있는지 짧게 전달하는 안내 장치입니다.

  1. Widget
    Widget

    상호작용 안내, 상태 표시, 게이지를 위젯 블루프린트로 구성합니다.

  2. Line Trace
    Line Trace

    카메라 방향으로 대상 액터를 찾고 상호작용 가능 여부를 확인합니다.

  3. Show Hide
    Show Hide

    대상이 있을 때만 위젯을 표시해 화면 정보를 줄입니다.

  4. Input
    Input

    표시된 대상과 입력 이벤트를 연결해 잘못된 실행을 막습니다.