사용자 인터페이스와 환경 연동
시선과 상호작용 범위를 판별해 안내 위젯을 표시하고 월드 상태와 UI 피드백이 일치하도록 연결합니다.
트리거로 상호작용을 만들었다면, 이제는 플레이어가 그 의미를 즉시 이해하도록 신호를 설계해야 합니다.
핵심은 사용자 인터페이스(User Interface, UI) 연동입니다.
플레이어가 오브젝트를 바라보거나 상호작용 범위에 들어왔을 때 적절한 안내를 띄우면, 다음 행동이 훨씬 자연스러워지고 시행착오도 줄어듭니다.
이번 절에서는 UI와 월드 상호작용을 끊김 없이 연결하는 방법을 다룹니다.
정리된 피드백 흐름을 적용하면 레벨의 정보 전달력이 올라가고, 플레이어 경험도 한층 매끄러워집니다.
환경 상호작용 UI는 플레이어 시선, 입력 가능 상태, 월드 이벤트 결과를 같은 시점에 표시해 조작 가능한 대상을 오해 없이 전달해야 합니다.
- 상호작용 신호 표시
Trace나 Overlap 결과가 유효할 때만 프롬프트를 띄우고, 대상이 바뀌면 표시 텍스트도 즉시 갱신합니다.
- 사용자 인터페이스 (UI) 기본 개념
언리얼 엔진에서는 주로 위젯 블루프린트(Widget Blueprint)를 사용하여 UI를 제작하고 화면에 표시합니다.
- 시선 기반 상호작용 구현
플레이어의 카메라 시선이 특정 오브젝트에 닿았을 때 이를 감지하고 UI를 표시하는 방식입니다.
- 사용자 인터페이스와 환경 연동 기준
정확성 표시 조건은 감지된 액터, 입력 가능 거리, 현재 상호작용 상태를 모두 만족할 때만 참이어야 합니다. 비용 매 프레임 위젯을 새로 만들지 않고 기존 위젯의 텍스트와 가시성만 바꿔 비용을 줄입니다. 확장성 문, 상자, NPC처럼 대상이 늘어나도 인터페이스 호출 규칙과 실패 피드백을 같은 함수 경로로 유지합니다. 예외 (예: E 키를 눌러 문 열기) 입력 안내가 남아 있으면 오작동처럼 보이므로, 상호작용 가능 범위를 벗어나면 UI를 숨깁니다.
- 정확성 표시 조건
감지된 액터, 입력 가능 거리, 현재 상호작용 상태를 모두 만족할 때만 참이어야 합니다.
- 비용 매 프레임 위젯
새로 만들지 않고 기존 위젯의 텍스트와 가시성만 바꿔 비용을 줄입니다.
- 확장성 문, 상자, NPC처럼 대상
늘어나도 인터페이스 호출 규칙과 실패 피드백을 같은 함수 경로로 유지합니다.
- 예외 (예
키를 눌러 문 열기) 입력 안내가 남아 있으면 오작동처럼 보이므로, 상호작용 가능 범위를 벗어나면 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패널에서 각 위젯의 속성(텍스트 내용, 이미지 소스, 글꼴, 크기)을 설정합니다.
- 팔레트(Palette)에서
-
그래프 (Graph)
- 위젯의 기능적 로직을 구현하는 블루프린트 그래프입니다.
Construct(위젯 생성 시),Destruct(위젯 제거 시),OnButtonClicked(버튼 클릭 시) 등 다양한 이벤트와 함수를 활용합니다.- 텍스트 내용 변경, 이미지 교체 등 동적인 UI 변화를 여기서 제어합니다.
위젯을 화면에 추가/제거
-
위젯 생성 및 화면 추가
- 블루프린트에서
Create Widget노드를 사용하여 위젯 블루프린트의 인스턴스를 생성합니다. - 생성된 위젯의 참조를 가져와
Add to Viewport노드를 호출하여 위젯을 화면에 표시합니다.
- 블루프린트에서
-
위젯 제거
- 위젯 참조를 가져와
Remove from Parent노드를 호출하여 위젯을 화면에서 제거합니다.
- 위젯 참조를 가져와
시선 기반 상호작용 구현
플레이어의 카메라 시선이 특정 오브젝트에 닿았을 때 이를 감지하고 UI를 표시하는 방식입니다.
정교한 상호작용에 주로 사용됩니다.
Line Trace (라인 트레이스)
- 역할: 특정 시작점에서 특정 방향으로 선(Ray)을 발사하여, 그 선이 어떤 오브젝트와 충돌하는지 감지하는 물리 쿼리입니다.
- 주요 노드:
Line Trace By ChannelStart: 라인 트레이스가 시작될 월드 좌표. (보통 카메라 컴포넌트의 월드 위치)End: 라인 트레이스가 끝날 월드 좌표. (Start에서 카메라의 앞쪽 방향 벡터에 일정 거리를 곱한 값을 더함)Trace Channel: 어떤 충돌 채널과 충돌을 감지할지 지정합니다. (예:Visibility,Camera)Draw Debug Type: 디버깅을 위해 라인 트레이스를 시각화합니다. (Line, Persistent, ForDuration 등)Out Hit: 충돌이 발생했을 때 충돌한 액터, 위치, 법선(Normal), 충돌 컴포넌트 등의 상세 정보를 반환합니다.
Line Trace를 활용한 상호작용 UI 구현 로직
선을 맞히는 것보다 이전 대상과 표시 상태를 함께 관리해 프롬프트 깜빡임을 줄이는 구조가 중요하다.
- Camera Forward
카메라 위치와 정면 방향으로 짧은 선을 만든다.
- Trace Channel
Visibility 또는 Interactable 전용 채널로 검사한다.
- Interface Check
Hit Actor가 상호작용 인터페이스를 구현했는지 본다.
- Prompt State
텍스트 표시, 갱신, 숨김을 이전 대상과 비교한다.
- Input
Interact Action이 현재 대상에만 전달되게 한다.
| 기준 | 판정 |
|---|---|
| UI 깜빡임 | PrevHitActor와 현재 Hit Actor를 비교해 상태 변경을 줄인다. |
| 성능 부담 | Tick 대신 Timer로 검사 간격을 조정한다. |
시선 기반 UI는 한 번 띄우는 것보다, 대상이 바뀌거나 사라질 때 위젯 참조와 표시 상태를 함께 정리하는 흐름이 중요합니다.
Line Trace가 맞은 액터만 보는 것이 아니라, 이전 대상과 현재 대상이 달라졌을 때 위젯 텍스트와 표시 상태를 함께 갱신해야 합니다.
- 카메라 앞 대상 확인
Trace 카메라 위치와 전방 벡터로 짧은 탐색선을 만들고 상호작용 가능 액터만 통과시킵니다.
- 참조를 한 번 생성
Widget 매 프레임 새 위젯을 만들지 않고 변수에 보관한 참조를 재사용합니다.
- 이전 대상과 비교
Actor PrevHitActor가 바뀌면 프롬프트 문구를 새 오브젝트 이름으로 바꿉니다.
- 충돌 없음은 숨김
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노드를 호출합니다.Start와End에 위에서 계산한 값을 연결합니다.Trace Channel을Visibility로 설정합니다.Draw Debug Type을ForDuration으로 설정하여 디버깅을 돕습니다.
Line Trace By Channel의Return 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가 남거나 깜박이지 않습니다.
- 규칙대상이 바뀌면 먼저 숨기고 다시 보여준다
규칙 대상이 바뀌면 먼저 숨기고 다시 보여준다 PrevHitActor와 CurrentHitActor 비교가 기준입니다.
- Idle대상 없음
Idle Trace 실패 시 위젯을 숨기고 이전 대상을 비웁니다.
- Candidate상호작용 후보
Candidate 캐스트 성공 후 거리와 잠금 상태를 확인합니다.
- Visible프롬프트 표시
Visible 위젯이 없으면 생성하고, 있으면 텍스트만 갱신합니다.
- Commit입력 실행
Commit Interact 입력 후 대상 함수 호출과 UI 정리를 함께 수행합니다.
사용자 인터페이스 (UI) 피드백 종류
상호작용에 대한 피드백은 텍스트 UI 외에도 다양하게 제공될 수 있습니다.
- 텍스트 프롬프트 (Text Prompt): E 키를 눌러 상호작용, 문 열기 등 가장 흔하고 명확한 피드백입니다.
- 아이콘/커서 변화: 상호작용 가능한 오브젝트 위에 마우스 커서가 올라가거나 시선이 닿았을 때, 커서 아이콘이 변하거나 전용 상호작용 아이콘이 표시됩니다.
- 오브젝트 하이라이트: 상호작용 가능한 오브젝트의 외곽선이 빛나거나 색상이 변하여 플레이어의 시선을 끕니다.
- 구현: 오브젝트의 머티리얼에 하이라이트 기능을 추가하고, 블루프린트에서
Set Scalar Parameter Value등으로 하이라이트 강도를 조절합니다. 또는Custom Depth Render와Post Process Material을 조합하여 아웃라인 효과를 구현합니다.
- 구현: 오브젝트의 머티리얼에 하이라이트 기능을 추가하고, 블루프린트에서
- 사운드 피드백: 상호작용 가능 영역에 진입하거나 오브젝트를 바라볼 때 미묘한 띵 소리나 UI 소리를 재생하여 청각적인 단서를 제공합니다.
- 애니메이션: 오브젝트 자체에 짧은 시각적 애니메이션(예: 스위치가 살짝 튀어나옴)을 주어 상호작용 가능성을 암시합니다.
피드백 채널은 많이 겹칠수록 좋은 것이 아니라, 플레이어가 지금 알아야 할 질문에 맞게 나누는 편이 명확합니다.
텍스트 프롬프트, 커서, 하이라이트, 사운드는 같은 의미를 반복하는 장식이 아니라 서로 다른 플레이어 질문에 답해야 합니다.
- PromptUI 입력 대상
Prompt 입력 키와 동작 이름을 짧게 표시합니다. 대상이 바뀌면 텍스트를 즉시 갱신합니다.
- Cursor상호작용 가능한가
Cursor 시선이 닿은 순간 가능 여부를 알려 주되 잠긴 대상과 가능한 대상을 구분합니다.
- Outline어느 오브젝트인가
Outline Custom Depth나 머티리얼 파라미터로 선택된 대상만 강조합니다.
- Sound상태가 바뀌었나
Sound 진입, 선택, 실패, 완료를 서로 다른 짧은 소리로 구분합니다.
- clarity한 메시지 한 의미
clarity 프롬프트에는 입력과 행동만 두고 설명문은 퀘스트 UI로 분리합니다.
- state상태별 다른 반응
state 가능, 잠김, 쿨다운, 완료 상태를 같은 색과 소리로 처리하지 않습니다.
- cleanup대상 이탈 정리
cleanup Trace 실패와 EndOverlap에서 위젯, 하이라이트, 사운드 루프를 함께 정리합니다.
사용자 인터페이스 연동 최적화 및 고려 사항
- 성능:
Event Tick에서Line Trace를 매 프레임 실행하는 것은 성능에 부담을 줄 수 있습니다.- 최적화:
Set Timer by Event노드를 사용하여Line Trace를 0.1초 또는 0.2초 간격으로 실행하거나, 플레이어가 움직일 때만Line Trace를 실행하는 등 업데이트 주기를 조절합니다. - 충돌 채널 최적화:
Trace Channel을Visibility대신Custom채널(예:Interactable)을 만들고, 상호작용 가능한 오브젝트에만 해당 채널을Block하도록 설정하여 불필요한 충돌 계산을 줄입니다.
- 최적화:
- 명확성: UI 피드백은 명확하고 간결해야 합니다. 너무 많은 정보나 혼란스러운 시각 효과는 피합니다.
- 일관성: 게임 내 모든 상호작용 가능한 오브젝트에 일관된 UI 피드백 방식을 적용하여 플레이어가 빠르게 학습할 수 있도록 합니다.
- 입력 매핑: 상호작용 키(예: E 키)는
Input Action으로 정의하여 플레이어가 키를 재설정할 수 있도록 합니다.
사용자 인터페이스와 환경 연동은 플레이어가 게임 세계와 소통하는 중요한 다리 역할을 합니다.
UI와 환경 연동은 시선 감지, 위젯 표시, 피드백 조건을 명확히 나누어 구현합니다.
입력 지점과 표시 조건을 함께 테스트하세요.
환경 UI는 플레이어가 무엇을 바라보고 무엇을 할 수 있는지 짧게 전달하는 안내 장치입니다.
- WidgetWidget
상호작용 안내, 상태 표시, 게이지를 위젯 블루프린트로 구성합니다.
- Line TraceLine Trace
카메라 방향으로 대상 액터를 찾고 상호작용 가능 여부를 확인합니다.
- Show HideShow Hide
대상이 있을 때만 위젯을 표시해 화면 정보를 줄입니다.
- InputInput
표시된 대상과 입력 이벤트를 연결해 잘못된 실행을 막습니다.