Choose your operating system:
Windows
macOS
Linux
프로젝트에서 플레이어가 UI 엘리먼트를 화면상에서 드래그 앤 드롭으로 상호작용할 수 있도록 했으면 싶은 때가 있습니다. 인터페이스 레이아웃 커스터마이징 (헬스 바 또는 유닛 프레임 위치 이동) 또는 인벤토리 화면같은 게임플레이 시스템 상호작용 (아이템 추가/제거) 등이 될 수 있습니다. UMG 에서 DragAndDropOperation 노드로 이러한 상호작용 유형을 생성하여 원하는 상호작용 방식에 맞게 상속된 블루프린트 함수 일부를 오버라이드하면 됩니다.
이 예제에서는 플레이어가 왼쪽 마우스 버튼으로 화면상의 헬스 바를 끌어 위치를 조정할 수 있도록 만드는 방법을 살펴봅니다. 이 가이드를 마칠 즈음엔 뷰포트 안에서 드래그하여 새 위치에 드롭할 수 있는 UI 위젯이 생길 것입니다.
이 튜토리얼에서는 실제 작동하는 생명력 표시줄을 만들기 보다, 그 방법만 보여드립니다. HUD 제작 방법은 UMG UI 디자이너 퀵스타트 가이드 문서를 참고하세요.
1 - 프로젝트 구성
시작하기에 앞서, 프로젝트 구성의 일부로 만들어야 하는 애셋이 몇 개 있습니다. 이 예제에서 드래그 앤 드롭으로 조작했으면 하는 HUD 요소는 HealthBar (생명력 표시줄)입니다. 이걸 직접 끌고 다니기 보다는, 그와 같은 모양을 한 DragWidget 이라는 위젯을 만들도록 하겠습니다. 그러면 생명력 표시줄 프로그래밍과 드래그 앤 드롭 기능을 분리할 수 있습니다.
여기서는 블루프린트 삼인칭 템플릿 프로젝트를 사용하겠습니다.
-
콘텐츠 브라우저 에서 세 개의 위젯 블루프린트 를 생성합니다. DragWidget , HealthBar , HUD 입니다.
-
콘텐츠 브라우저 에 우클릭 하고 블루프린트 클래스 를 만들어 DragDropOpertion 클래스를 기반으로 한 뒤 이름을 WidgetDrag 라 합니다.
이 전문 블루프린트 클래스 덕에 정보를 드래그 앤 드롭 동작의 일부로 전달할 수 있습니다.
-
WidgetDrag 을 열고 User Widget 변수를 생성한 뒤 WidgetReference 라 하고, Editable (편집가능) 및 Expose on Spawn (스폰시 노출)을 체크합니다.
화면에서 끌고다니고자 하는 UMG 위젯을 저장하는 데 사용될 것입니다.
-
Vector 2D 변수를 만들어 DragOffset 이라 합니다. Instance Editable 및 Expose on Spawn 박스를 체크합니다.
위젯 드래그를 시작할 때와 드롭할 때 위치 오프셋에 사용될 것입니다.
-
Drag Widget 블루프린트를 컴파일 , 저장 합니다.
-
Drag Widget 블루프린트를 열고 User Widget 변수를 만들어 WidgetReference 라 합니다. Instance Editable , Expose on Spawn 를 체크합니다.
-
Drag Widget 블루프린트를 컴파일 , 저장 합니다.
프로젝트 구성이 완료되었으니, 다음에는 드래그 가능하도록 하려는 UI 조각인 HealthBar 위젯 블루프린트 작업을 시작하겠습니다.
2 - 생명력 표시줄 위젯 구성
이번 단계에서는 왼쪽 마우스 버튼이 언제 눌렸는지 알아내어 눌린 스크린 스페이스 위치를 저장합니다. 또한 DetectDragIfPressed 를 사용하여 플레이어가 지정된 키로 드래그를 하고 있는지 알아냅니다.
-
HealthBar 위젯 블루프린트를 열고 계층구조 창에서 Canvas Panel 을 삭제합니다.
-
Size Box 를 추가하고 박스에 Progress Bar 를 추가합니다. Size Box 의 디테일 패널 에서 Width 와 Height Override 를 500x50 으로 설정합니다.
또는 Progress Bar 스타일을 정할 수 있습니다. 아래에서 조정된 프리뷰를 Desired on Screen , Percent 를 1.0 으로 설정하여 Progress Bar 를 가득 채우고 색을 변경했습니다.
2.1 - 마우스 버튼 클릭 시 함수 스크립트
여기서는 플레이어가 왼쪽 마우스 버튼 드래그 중인지 결정할 수 있습니다.
-
이벤트 그래프 에서 OnMouseButtonDown , OnDragDetected 오버라이드를 추가합니다. 이벤트 그래프에 각 오버라이드에 대한 탭이 생성됩니다.
별도의 커스텀 스크립트를 호출하기 위해 오버라이드할 수 있는 함수가 여럿 있습니다. 여기서는 마우스 버튼이 언제 눌렸는지 검사를 조금 하고 위젯 드래그가 감지되면 무슨 일이 벌어지는지를 설정하겠습니다.
-
OnMouseButtonDown 탭을 선택하고 거기서 My Geometry 핀을 끌어 놓고 Absolute to Local 노드를 추가합니다.
-
Mouse Event 핀을 끌어 놓고 Get Screen Space Position 노드를 추가한 뒤 Return Value 를 Absolute Coordinate 에 연결합니다.
여기서 마우스 버튼 눌림을 등록한 스크린 스페이스 위치를 구하여, Health Bar 위젯의 절대 좌표를 로컬 스페이스로 변환합니다. 그러면 플레이어가 위젯의 어디를 실제로 클릭했는지 알 수 있으며, 그를 통해 위젯을 드롭했을 때 어디에 배치할 것인지 결정할 수 있으니, 그 위치를 변수에 저장하겠습니다.
-
Absolute to Local 의 Return Value 핀에 우클릭하고 변수로 승격 후 Drag Offset 이라 합니다.
On Mouse Button Down 노드에 오류가 보여도 걱정하지 마세요, 함수를 완료하면 사라질 것입니다.
-
그래프에 우클릭하고 Detect Drag if Pressed 노드를 추가합니다. Drag Key 를 Left Mouse Button 으로 설정합니다.
-
나머지 핀을 연결합니다.
-
Mouse Event 를 Pointer Event 에 연결합니다.
-
Detect Drag if Pressed 의 Return Value 핀을 Return Node 에 연결합니다.
-
Exec 핀을 네 노드에 걸쳐 연결합니다.
그러면 플레이어가 좌클릭 드래그 중인지 알 수 있고, On Drag Detected 스크립트를 시작할 수 있습니다.
-
-
HealthBar 블루프린트를 컴파일 , 저장 합니다.
2.2 - 드래그 감지 시 함수 스크립트
이번 단계에서는 플레이어가 사실상 HealthBar 를 화면에서 드래그할 때 무슨 일이 벌어질지를 결정합니다.
-
OnDragDetected 탭을 선택합니다. OnDragDetected 노드에서 우클릭하고 Create Widget 노드를 추가합니다. Class 는 Drag Widget 으로 설정합니다.
-
Widget Reference 핀에서 Self 노드를 연결합니다. Return Value 를 변수로 승격 하여 Dragged Widget 라 하고 핀을 연결합니다.
이제 드래그 위젯이 생성되면, 기존 Health Bar 위젯으로의 레퍼런스가 있을 것입니다. 더미 드래그 위젯도 변수로 승격시켜 나중에 접근하고 위젯을 드롭하기로 했을 때 표시에서 제거할 수 있도록 합니다.
-
우클릭 하고 DragAndDropOperation 노드 생성 후 Class 는 Widget Drag 으로, Pivot 은 Mouse Down 으로 설정합니다.
피벗은 드래그 도중 포인터를 기준으로 위젯 비주얼이 나타날 위치를 결정합니다.
-
다음 노드를 DragAndDropOperation 노드 핀에 연결합니다.
-
Dragged Widget Set 의 실행 선을 Return Node 로 통과시킵니다.
-
Self 는 Widget Reference 에,
-
Dragged Widget 는 Default Drag Visual 에,
-
Drag Offset 는 Drag Offset 에 연결합니다.
위에서 어떤 위젯 블루프린트가 우리 레퍼런스인지, 드래그 비주얼은 무엇이어야 하는지를 나타내고, 드래그 시작을 위한 오프셋을 제공해 주었습니다. 노드에 기본적으로 오프셋 핀이 있지만, 자체 계산한 별도의 핀을 사용하여 마우스 버튼이 눌렸을 때 드래그 시작 위치를 결정하고 있습니다.
-
-
HealthBar 블루프린트를 컴파일 , 저장 합니다.
이제 남은 몇 가지 작업은 플레이어가 왼쪽 마우스 버튼을 뗄 때 무슨 일이 벌어지는가 결정하고 OnDrop 함수를 수행하는 것입니다.
3 - 드랍 시 함수 구성
여기서는 메인 HUD 위젯 블루프린트를 구성하고 OnDrop 함수 실행 시 어떤 일을 할 것인가 오버라이드를 설정합니다.
-
HUD 위젯 블루프린트를 열고, Canvas Panel 에 대한 디테일 패널에서 비저빌리티 를 Visible 로 설정합니다.
Health Bar 위젯 안에서 드래그 감지를 하고 있지만, 왼쪽 마우스 버튼을 놓을 때는 HUD 위젯 블루프린트 안에 드롭하고자 합니다. HUD 가 히트 감지 정보를 받기 위해서는, 그 비저빌리티 를 Visible 로 설정해야 합니다.
-
팔레트 창에서 Health Bar 위젯을 Canvas 에 추가합니다.
-
이벤트 그래프 모드로 가 내 블루프린트 패널에서 OnDrop 함수 오버라이드를 추가합니다.
-
OnDrop 노드에서 Operation 을 끌어 놓고 Cast to WidgetDrag 노드를 추가합니다. 그런 다음 Get Widget Reference 를 추가하고 As Widget Drag 핀을 Widget Reference 및 Drag Offset 노드에 연결합니다.
그러면 OnDrop 함수의 일부로 어떤 유형의 작업이 이루어지고 있는지 검사합니다. Widget Drag 인지? 그렇다면, (드래그중인 위젯으로 전달한) WidgetReference 와 아울러 DragOffset (또는 드래그를 시작한 위치)를 구합니다.
-
My Geometry 핀에서 Absolute to Local 노드를 추가합니다. Pointer Event 핀에서 GetScreenSpacePosition 노드를 추가합니다.
위젯을 드롭하기 위해 2D 스페이스에서 왼쪽 마우스 버튼을 놓은 위치를 알려줍니다. 여기에서 DragOffset 을 빼 위젯을 드롭했을 때 어디에 놓을지를 결정합니다.
-
Vector2D - Vector 2D 노드를 추가하고 Absolute to Local 의 Return Value 에서 DragOffset 을 뺍니다.
-
우클릭하고 Remove from Parent , Add to Viewport , Set Position in Viewport 노드를 추가합니다. 모든 3 노드의 Exec 핀을 위 순서대로 연결하고, Set Position in Viewport 노드를 Return Node 에 연결합니다.
-
다음과 같이 연결하고 조정합니다:
-
Widget Reference 핀 > 모든 3 노드의 Target 핀
-
Vector2D - Vector 2D 노드의 Return Value 핀 - Position 핀
-
Remove DPIScale 해제
-
Return Value 체크
Remove DPIScale 는 해제하고 Return Value 는 체크하는 이유는 DPI 스케일링 제거는 할 필요 없이 true 를 반환하도록 이 함수를 처리해 왔기 때문입니다. 이 스크립트를 통해, 먼저 기존 Health Bar 위젯을 제거한 뒤 화면의 Drag Offset 기준 새 위치에 다시 추가합니다.
-
-
HUD 위젯 블루프린트를 컴파일 , 저장 합니다.
HUD 가 드래그중인 위젯 드롭을 처리하고 Health Bar 를 표시하도록 구성했습니다. 다음에는, Dragged Widget 을 Health Bar 모양과 비슷하게 구성하고 캐릭터 블루프린트에게 HUD 를 뷰포트에 추가하도록 할 것입니다.
4 - 드래그 위젯 스크립트
이번 단계에서는, 비주얼을 담당할 DragWidget 을 구성하겠습니다.
-
DragWidget 위젯 블루프린트를 열고 Canvas Panel 을 Size Box 로 대체하고 자손 Border 설정을 합니다.
-
SizeBox 이름을 WidgetSize 로 변경하고 isVariable 을 true 로 설정한 뒤, Width Override 와 Height Override 를 체크합니다.
Size Box 의 Width 와 Height 를 Health Bar 위젯의 크기에 맞게 설정하도록 하겠습니다.
-
Border 의 경우, Brush Color 를 Black 으로, Alpha 를 0.5 로 하여 약간 반투명하게 만듭니다.
이 예제에서 드래그 비주얼로는 Health Bar 의 실루엣을 사용하면서 실제 Health Bar 는 같은 위치에 유지합니다.
-
이벤트 그래프 에서, Event Construct 를 끌어 놓고 Cast to HealthBar 노드를 추가합니다. Widget Reference 를 끌어 놓고 Object 핀에 연결합니다.
-
As Health Bar 핀에서 Get Desired Size 노드를 추가합니다. Return Value 핀을 Break Vector 2D 노드에 연결합니다.
그러면 Size Box 에 설정할 수 있는 Health Bar 크기가 나옵니다. 오버라이드를 수동 입력할 수도 있지만, 그랬다면 Health Bar 크기 변경 시 여기서도 변경해 줘야 할 것입니다.
-
우클릭하고 Set Height Override 및 Set Widget Override 노드를 추가하고 각각 Cast to HealthBar 노드에 연결합니다. 그런 다음 Widget Size 노드를 끌어 놓습니다.
-
다음과 같이 핀을 연결합니다.
-
Widget Size > Target
-
Break Vector 2D X > In Height Override
-
Break Vector 2D Y > In Width Override
-
-
DragWidget 블루프린트를 컴파일 , 저장 합니다.
5 - HUD 위젯을 뷰포트에 추가
마지막으로, HUD 위젯 블루프린트를 Character 블루프린트의 뷰포트에 추가하고 Mouse Cursor 를 활성화하여 드래그 위치를 확인할 수 있도록 해야 합니다.
-
콘텐츠 브라우저 에서 Content/ThirdPersonBP/Blueprints 아래 ThirdPersonCharacter 블루프린트를 엽니다.
-
Event Begin Play 노드에서 Create Widget 노드를 추가하고 Class 를 HUD 로 설정합니다. Add to Viewport 노드를 생성하고 SET Show Mouse Cursor 에 연결합니다. Get Player Controller 노드를 추가하고 Return Value 를 SET Target 에 연결합니다.
-
컴파일 , 저장 , 및 플레이 를 클릭하여 위젯을 드래그 앤 드롭합니다.
최종 결과
에디터에서 플레이 후, 화면에서 Health Bar 를 좌클릭 드래그 후 새 위치에 드롭합니다.
이는 드래그 앤 드롭 프로세스를 시작하는 데 필요한 엘리먼트 예제일 뿐입니다. 플레이어가 위젯을 세이프 존 외부 혹은 다른 위젯 위에 드래그하지는 않았나 추가적인 확인이 필요할 수 있습니다.