Confirmation Dialogue Widget - Unreal Common UI Tutorial Part 3

Confirmation Dialogue (CommonText) Style 설정하기

Vertical Box & Button 2개 모두 중앙 정렬 맞추기

Vertical Box → Wrap with Common Border

Vertical Box 중앙 정렬하기

BorderStyle_Background 만들어서 Common Border에 적용하기

Confirmation Dialogue 위젯 배경 색깔 설정하기

Button 두 개 모두 중앙 정렬하기

버튼 사이에 Spacer 넣고 Fill 채우기

Horizontal Box Top Padding을 20 추가해서 Dialogue Message와 간격 띄우기


Exit 버튼 누르면 WBP_ConfirmationDialogue 화면 나오게 하기
함수로 접기
Exit 버튼 누르면 WBP_ConfirmationDialogue 화면 나오게 하기

✅ Pure 함수로 전환
| 항목 | Non-Pure | ✅ Pure |
|---|---|---|
| 실행 핀 (흰색) | 있음 | ❌ 없음 |
| 데이터 핀 (파란색 등) | 있음 | 있음 |
| 상태 변경 | 가능 | ❌ 없음 (읽기 전용) |
| 실행 순서 의존 | 있음 | ❌ 없음 |
| 대표 예시 | Set Text, Add Child | Get Player Controller, Get Health, Calculate Damage |
Pure로 만들면 생기는 장점
| 장점 | 설명 |
|---|---|
| ✅ 노드 연결이 간결 | 실행 핀이 필요 없어 선이 줄어듦 |
| ✅ 계산 함수처럼 즉시 사용 가능 | 예: 다른 노드의 입력 핀에 바로 꽂기 가능 |
| ✅ 읽기 전용 함수로 안전 | 내부 상태를 바꾸지 않음 |
| ✅ 블루프린트에서 "Get"류 함수로 직관적으로 사용 가능 | Getter 역할에 적합 |
Pure 함수로 만들면 안 되는 경우
이런 건 Pure로 하면 안 됨:
Add to Viewport
Play Animation
Set Text
Spawn Actor

노란 박스 변수로 승격 → Default Value에 문구 입력

Exit 누르면 WBP_ConfirmationDialogue 위젯 호출

Border → Wrap with Backgroud Blur

블러 강도 5.0

이벤트 디스패쳐 생성

Create Event의 Create a matching function


언리얼에서 UI 위젯은 계층 구조(Tree)로 구성:
Viewport
└── MainMenu (UserWidget)
├── SettingsPanel (VerticalBox)
└── ExitDialog (Overlay)
Remove from Parent는 이 중에서 자기 자신을 부모 컨테이너(Parent)로부터 제거하는 것
void UWidget::RemoveFromParent()
{
if (UPanelWidget* Parent = GetParent())
{
Parent->RemoveChild(this);
}
}
🚨 주의할 점
| 항목 | 설명 |
|---|---|
| ❌ 파괴(Destroy) 아님 | 단지 부모에서 분리만 되는 것, 메모리엔 여전히 남아 있음 |
| ✅ 재사용 가능 | 나중에 AddToViewport()로 다시 붙이면 다시 보임 |
| ⚠️ 여러 부모 중복 불가 | 하나의 위젯은 동시에 하나의 Parent만 가질 수 있음 |

노란색 부분 변수로 승격하고 이름 바꾸기


이미 존재하는 대화창(확인창)이 있어? → 그걸 반환
없어? → 새로 만들어서 변수에 저장한 뒤 반환
GET — WBP Confirmation Dialogue 변수 확인WBP Confirmation Dialogue 라는 변수는 확인창 (예: “Are you sure you want to exit the game?”) 위젯의 참조를 담는 변수Is Valid 로 “이미 만들어져 있는지”를 검사🔍 의미: ****이미 존재하면 재사용하고, 없으면 새로 만든다.
Is Valid 분기Is Valid → “이 변수가 null(=없음)이 아닌가?” 검사Get Owning PlayerWBP_MainMenu)을 띄운 플레이어 컨트롤러를 가져옴🔍 의미: “이 확인창은 어떤 플레이어의 화면에 표시될 것인가?”
Create WBP Confirmation Dialogue WidgetWBP_ConfirmationDialogue)을 새로 생성하는 노드Get Owning Player 결과를 연결Return Value)가 새로 생성된 위젯 인스턴스가 됨SET — 변수에 저장WBP Confirmation Dialogue 변수에 저장합니다.GetDialogue() 호출 시, 이미 존재하는 동일 인스턴스를 재사용할 수 있습니다.🔍 의미: “다음에 또 필요하면 새로 만들지 말고 이걸 써라.”
Return NodeWBP Confirmation Dialogue 변수를 반환GetDialogue()
│
├── [Get] WBP Confirmation Dialogue
│ ├── If Valid → 바로 반환
│ └── If Not Valid → 새로 생성
│
├── [Get Owning Player]
├── [Create WBP Confirmation Dialogue Widget]
├── [Set] WBP Confirmation Dialogue = 새 위젯
│
└── Return (WBP Confirmation Dialogue)
| 항목 | 설명 |
|---|---|
| ✅ 효율적 | 이미 생성된 위젯을 재사용하므로 불필요한 CreateWidget 호출 방지 |
| ✅ 안정적 | null 참조 오류 방지 (IsValid 체크로 안전함) |
| ✅ 유지보수 용이 | 언제든 동일한 함수로 “대화창 가져오기” 가능 |
| ✅ 깔끔한 코드 | GetDialogue() 한 줄로 필요한 위젯 확보 가능 |

MB_Exit 버튼 클릭 시 “종료 확인 다이얼로그”를 띄우는 로직
Unbind All Events from Input Dispatch 노드 추가(1) Exit 버튼 클릭
↓
(2) GetDialogue() → 기존 다이얼로그 위젯 가져오기 (없으면 생성)
↓
(3) ShowDialogue() → 메시지 표시 : “정말 종료하시겠습니까?”
↓
(4) UnbindAllEventsFromInputDispatch() → 기존 콜백들 제거
↓
(5) CreateEvent(OnExitConfirmation) → 새로운 콜백 준비
↓
(6) BindEventToInputDispatch() → 새 이벤트(Exit YES/NO) 바인딩
Get DialogueGetDialogue)를 호출해서WBP_ConfirmationDialogue 인스턴스를 가져옴Show DialogueMessage 핀에는 표시할 텍스트 (Exit Message = “Are you sure you want to exit the game?”)가 들어감WBP_ConfirmationDialogue 위젯"확인창 위젯을 불러서 메시지 띄워줘."
Unbind All Events from Input Dispatch여기가 핵심👇
⚙️ 역할:
“이 다이얼로그 위젯에 이전에 바인딩된 입력(YES/NO 응답) 이벤트들을 전부 해제해라.”
이전에 이 다이얼로그를 썼을 때 남아 있던 이전 콜백(이벤트 리스너) 들을 다 지워주는 단계
🧠 왜 필요?
WBP_ConfirmationDialogue는 여러 번 재사용될 수 있는 위젯
그런데 만약 매번 새로운 이벤트를 바인딩만 하고 언바인딩을 안 하면 이런 문제가 생김
⚠️ 문제 시나리오
BindEvent 연결됨BindEvent 추가됨결과:
🔁 “YES”를 한 번 눌렀는데 OnExitConfirmation 이벤트가 여러 번 실행됨
그래서, “새로 바인딩하기 전에 무조건 이전 걸 다 언바인딩(Unbind)” 해야 함
Create Event“이 다이얼로그에서 YES 또는 NO를 선택하면,
WBP_MainMenu의 OnExitConfirmation(bool bYes) 함수를 호출하라.”
Bind Event to Input DispatchOnExitConfirmation 이벤트에 연결
| Animation | Render Opacity (0.00 → 0.25) |
|---|---|
FadeIn | 0.0 → 1.0 |
FadeOut | Play Animation Reserve |

FadeIn 만 애니메이션 만들고 FadeOut 은 만든 애니메이션 reverse 해주기
다이얼로그(UI 창)가 FadeOut 애니메이션으로 서서히 사라지고,
그 애니메이션이 끝난 뒤 Remove from Parent로 위젯을 화면에서 완전히 제거하는 구조
여기서 Get End Time + Delay 조합은 “애니메이션이 다 끝난 뒤 정확한 타이밍에 Remove 실행하기”용입
Play Animation (FadeIn, Reverse)FadeIn 애니메이션을 Reverse 모드(역재생) 로 재생 → 즉, “페이드아웃(FadeOut)”처럼 서서히 사라지는 효과Get End TimeFadeIn 애니메이션의 전체 길이(재생 시간) 를 가져오는 노드Get End Time의 반환값 = 0.8“이 애니메이션은 몇 초짜리인가?”를 자동으로 구하는 노드
DelayGet End Time의 값을 Delay Duration으로 연결“애니메이션이 끝날 때까지 기다렸다가, 그 다음에 실행해라.”
Remove from Parent→ 화면에서 완전히 사라짐
이걸 애니 끝나기 전에 실행하면 FadeOut이 끝나기도 전에 갑자기 꺼져버리므로,
Delay(GetEndTime)을 둬서 자연스럽게 마무리
[Button Yes/No Clicked]
↓
Call Input Dispatch (이벤트 전달)
↓
Play Animation (FadeIn, Reverse) → 페이드아웃 시작
↓
Get End Time (FadeIn 길이 구함)
↓
Delay (그 길이만큼 대기)
↓
Remove from Parent (위젯 완전히 제거)
| 장점 | 설명 |
|---|---|
| ✅ 자동 타이밍 | 애니메이션 길이를 하드코딩할 필요 없음 (0.8초, 1.2초 등 자동 감지) |
| ✅ 유지보수 편함 | 나중에 FadeIn 애니 길이 수정해도 Delay 자동 맞춰짐 |
| ✅ 부드러운 전환 | FadeOut이 다 끝난 뒤 위젯이 제거돼 자연스럽게 사라짐 |
FadeIn 애니메이션을 정방향(Forward) 으로 재생해서 투명도 0 → 1 로 자연스럽게 나타나게 함이게 없으면 위젯이 바로 1.0 투명도로 튀어나옴 (뚝 하고 나타나는 느낌)
Call Input Dispatch 로 상위(MainMenu)에게 “YES/NO” 신호를 보냄Play Animation (FadeIn, Reverse) 실행 → FadeIn을 역재생해서 “서서히 사라짐(FadeOut)” 효과를 냄GetEndTime → Delay → Remove from Parent 로 애니메이션이 끝난 뒤 위젯을 완전히 제거💡 이게 페이드아웃 타이밍 제어 부분
→ “YES/NO 눌렀을 때 다이얼로그가 부드럽게 닫히게 하려는 구조”
| 단계 | 이벤트 | 동작 | 애니메이션 |
|---|---|---|---|
| ① | Event Pre Construct | 위젯 생성 시 | FadeIn (Forward) — 서서히 등장 |
| ② | OnClicked(Yes/No) | 사용자 입력 | FadeIn (Reverse) — 서서히 사라짐 |
| ③ | Delay 후 Remove | 애니 끝난 뒤 | 위젯 제거 |
| 구분 | 이유 |
|---|---|
Event Pre Construct에서 FadeIn | 다이얼로그가 나타날 때 부드럽게 보이게 하려고 |
Play Animation (Reverse) | 동일한 FadeIn 애니를 역재생해서 FadeOut 효과로 재사용 |
GetEndTime + Delay | FadeOut 끝나는 시점까지 기다렸다가 제거하기 위해 |
Remove from Parent | 화면에서 완전히 제거 |
Event Pre Construct에서는 등장 시 FadeIn을,버튼 클릭 시에는 퇴장용 FadeOut(=FadeIn Reverse) 를 실행하는 구조
→ 다이얼로그가 자연스럽게 “나타났다 → 사라지는” 완성된 UI 흐름