드래그 앤 드롭 UI 제작

UMG 로 드래그 앤 드롭 가능한 UI 위젯을 만드는 법을 보여드립니다.

Choose your operating system:

Windows

macOS

Linux

프로젝트에서 플레이어가 UI 엘리먼트를 화면상에서 드래그 앤 드롭으로 상호작용할 수 있도록 했으면 싶은 때가 있습니다. 인터페이스 레이아웃 커스터마이징 (헬스 바 또는 유닛 프레임 위치 이동) 또는 인벤토리 화면같은 게임플레이 시스템 상호작용 (아이템 추가/제거) 등이 될 수 있습니다. UMG 에서 DragAndDropOperation 노드로 이러한 상호작용 유형을 생성하여 원하는 상호작용 방식에 맞게 상속된 블루프린트 함수 일부를 오버라이드하면 됩니다.

이 예제에서는 플레이어가 왼쪽 마우스 버튼으로 화면상의 헬스 바를 끌어 위치를 조정할 수 있도록 만드는 방법을 살펴봅니다. 이 가이드를 마칠 즈음엔 뷰포트 안에서 드래그하여 새 위치에 드롭할 수 있는 UI 위젯이 생길 것입니다.

이 튜토리얼에서는 실제 작동하는 생명력 표시줄을 만들기 보다, 그 방법만 보여드립니다. HUD 제작 방법은 UMG UI 디자이너 퀵스타트 가이드 문서를 참고하세요.

1 - 프로젝트 구성

시작하기에 앞서, 프로젝트 구성의 일부로 만들어야 하는 애셋이 몇 개 있습니다. 이 예제에서 드래그 앤 드롭으로 조작했으면 하는 HUD 요소는 HealthBar (생명력 표시줄)입니다. 이걸 직접 끌고 다니기 보다는, 그와 같은 모양을 한 DragWidget 이라는 위젯을 만들도록 하겠습니다. 그러면 생명력 표시줄 프로그래밍과 드래그 앤 드롭 기능을 분리할 수 있습니다.

여기서는 블루프린트 삼인칭 템플릿 프로젝트를 사용하겠습니다.

  1. 콘텐츠 브라우저 에서 세 개의 위젯 블루프린트 를 생성합니다. DragWidget , HealthBar , HUD 입니다.

    DragDrop1.png

  2. 콘텐츠 브라우저 우클릭 하고 블루프린트 클래스 를 만들어 DragDropOpertion 클래스를 기반으로 한 뒤 이름을 WidgetDrag 라 합니다.

    DragDrop2.png

    이 전문 블루프린트 클래스 덕에 정보를 드래그 앤 드롭 동작의 일부로 전달할 수 있습니다.

  3. WidgetDrag 을 열고 User Widget 변수를 생성한 뒤 WidgetReference 라 하고, Editable (편집가능) 및 Expose on Spawn (스폰시 노출)을 체크합니다.

    DragDrop3a1.png

    화면에서 끌고다니고자 하는 UMG 위젯을 저장하는 데 사용될 것입니다.

  4. Vector 2D 변수를 만들어 DragOffset 이라 합니다. Instance Editable Expose on Spawn 박스를 체크합니다.

    DragDrop3b1.png

    위젯 드래그를 시작할 때와 드롭할 때 위치 오프셋에 사용될 것입니다.

  5. Drag Widget 블루프린트를 컴파일 , 저장 합니다.

  6. Drag Widget 블루프린트를 열고 User Widget 변수를 만들어 WidgetReference 라 합니다. Instance Editable , Expose on Spawn 를 체크합니다.

    UpdatedDragDrop2.1.png

  7. Drag Widget 블루프린트를 컴파일 , 저장 합니다.

프로젝트 구성이 완료되었으니, 다음에는 드래그 가능하도록 하려는 UI 조각인 HealthBar 위젯 블루프린트 작업을 시작하겠습니다.

2 - 생명력 표시줄 위젯 구성

이번 단계에서는 왼쪽 마우스 버튼이 언제 눌렸는지 알아내어 눌린 스크린 스페이스 위치를 저장합니다. 또한 DetectDragIfPressed 를 사용하여 플레이어가 지정된 키로 드래그를 하고 있는지 알아냅니다.

  1. HealthBar 위젯 블루프린트를 열고 계층구조 창에서 Canvas Panel 을 삭제합니다.

  2. Size Box 를 추가하고 박스에 Progress Bar 를 추가합니다. Size Box 의 디테일 패널 에서 Width Height Override 500x50 으로 설정합니다.

    DragDrop4a.png

    또는 Progress Bar 스타일을 정할 수 있습니다. 아래에서 조정된 프리뷰를 Desired on Screen , Percent 1.0 으로 설정하여 Progress Bar 를 가득 채우고 색을 변경했습니다.

    DragDrop4b.png

2.1 - 마우스 버튼 클릭 시 함수 스크립트

여기서는 플레이어가 왼쪽 마우스 버튼 드래그 중인지 결정할 수 있습니다.

  1. 이벤트 그래프 에서 OnMouseButtonDown , OnDragDetected 오버라이드를 추가합니다. 이벤트 그래프에 각 오버라이드에 대한 탭이 생성됩니다.

    DragDrop5.1.png

    별도의 커스텀 스크립트를 호출하기 위해 오버라이드할 수 있는 함수가 여럿 있습니다. 여기서는 마우스 버튼이 언제 눌렸는지 검사를 조금 하고 위젯 드래그가 감지되면 무슨 일이 벌어지는지를 설정하겠습니다.

  2. OnMouseButtonDown 탭을 선택하고 거기서 My Geometry 핀을 끌어 놓고 Absolute to Local 노드를 추가합니다.

  3. Mouse Event 핀을 끌어 놓고 Get Screen Space Position 노드를 추가한 뒤 Return Value 를 Absolute Coordinate 에 연결합니다.

    DragDrop6.png

    여기서 마우스 버튼 눌림을 등록한 스크린 스페이스 위치를 구하여, Health Bar 위젯의 절대 좌표를 로컬 스페이스로 변환합니다. 그러면 플레이어가 위젯의 어디를 실제로 클릭했는지 알 수 있으며, 그를 통해 위젯을 드롭했을 때 어디에 배치할 것인지 결정할 수 있으니, 그 위치를 변수에 저장하겠습니다.

  4. Absolute to Local Return Value 핀에 우클릭하고 변수로 승격 Drag Offset 이라 합니다.

    DragDrop7.png

    On Mouse Button Down 노드에 오류가 보여도 걱정하지 마세요, 함수를 완료하면 사라질 것입니다.

  5. 그래프에 우클릭하고 Detect Drag if Pressed 노드를 추가합니다. Drag Key Left Mouse Button 으로 설정합니다.

  6. 나머지 핀을 연결합니다.

    • Mouse Event Pointer Event 에 연결합니다.

    • Detect Drag if Pressed Return Value 핀을 Return Node 에 연결합니다.

    • Exec 핀을 네 노드에 걸쳐 연결합니다.

    DragDrop8.png

    그러면 플레이어가 좌클릭 드래그 중인지 알 수 있고, On Drag Detected 스크립트를 시작할 수 있습니다.

  7. HealthBar 블루프린트를 컴파일 , 저장 합니다.

2.2 - 드래그 감지 시 함수 스크립트

이번 단계에서는 플레이어가 사실상 HealthBar 를 화면에서 드래그할 때 무슨 일이 벌어질지를 결정합니다.

  1. OnDragDetected 탭을 선택합니다. OnDragDetected 노드에서 우클릭하고 Create Widget 노드를 추가합니다. Class Drag Widget 으로 설정합니다.

    UpdatedDragDrop1.png

  2. Widget Reference 핀에서 Self 노드를 연결합니다. Return Value 를 변수로 승격 하여 Dragged Widget 라 하고 핀을 연결합니다.

    UpdatedDragDrop3.png

    이제 드래그 위젯이 생성되면, 기존 Health Bar 위젯으로의 레퍼런스가 있을 것입니다. 더미 드래그 위젯도 변수로 승격시켜 나중에 접근하고 위젯을 드롭하기로 했을 때 표시에서 제거할 수 있도록 합니다.

  3. 우클릭 하고 DragAndDropOperation 노드 생성 후 Class Widget Drag 으로, Pivot Mouse Down 으로 설정합니다.

    UpdatedDragDrop4.png

    피벗은 드래그 도중 포인터를 기준으로 위젯 비주얼이 나타날 위치를 결정합니다.

  4. 다음 노드를 DragAndDropOperation 노드 핀에 연결합니다.

    • Dragged Widget Set 의 실행 선을 Return Node 로 통과시킵니다.

    • Self Widget Reference 에,

    • Dragged Widget Default Drag Visual 에,

    • Drag Offset Drag Offset 에 연결합니다.

    UpdatedDragDrop5.png

    위에서 어떤 위젯 블루프린트가 우리 레퍼런스인지, 드래그 비주얼은 무엇이어야 하는지를 나타내고, 드래그 시작을 위한 오프셋을 제공해 주었습니다. 노드에 기본적으로 오프셋 핀이 있지만, 자체 계산한 별도의 핀을 사용하여 마우스 버튼이 눌렸을 때 드래그 시작 위치를 결정하고 있습니다.

  5. HealthBar 블루프린트를 컴파일 , 저장 합니다.

이제 남은 몇 가지 작업은 플레이어가 왼쪽 마우스 버튼을 뗄 때 무슨 일이 벌어지는가 결정하고 OnDrop 함수를 수행하는 것입니다.

3 - 드랍 시 함수 구성

여기서는 메인 HUD 위젯 블루프린트를 구성하고 OnDrop 함수 실행 시 어떤 일을 할 것인가 오버라이드를 설정합니다.

  1. HUD 위젯 블루프린트를 열고, Canvas Panel 에 대한 디테일 패널에서 비저빌리티 Visible 로 설정합니다.

    DragDrop13.png

    Health Bar 위젯 안에서 드래그 감지를 하고 있지만, 왼쪽 마우스 버튼을 놓을 때는 HUD 위젯 블루프린트 안에 드롭하고자 합니다. HUD 가 히트 감지 정보를 받기 위해서는, 그 비저빌리티 Visible 로 설정해야 합니다.

  2. 팔레트 창에서 Health Bar 위젯을 Canvas 에 추가합니다.

    DragDrop14.png

  3. 이벤트 그래프 모드로 가 내 블루프린트 패널에서 OnDrop 함수 오버라이드를 추가합니다.

    DragDrop15.png

  4. OnDrop 노드에서 Operation 을 끌어 놓고 Cast to WidgetDrag 노드를 추가합니다. 그런 다음 Get Widget Reference 를 추가하고 As Widget Drag 핀을 Widget Reference Drag Offset 노드에 연결합니다.

    DragDrop16.png

    그러면 OnDrop 함수의 일부로 어떤 유형의 작업이 이루어지고 있는지 검사합니다. Widget Drag 인지? 그렇다면, (드래그중인 위젯으로 전달한) WidgetReference 와 아울러 DragOffset (또는 드래그를 시작한 위치)를 구합니다.

  5. My Geometry 핀에서 Absolute to Local 노드를 추가합니다. Pointer Event 핀에서 GetScreenSpacePosition 노드를 추가합니다.

    DragDrop17.png

    위젯을 드롭하기 위해 2D 스페이스에서 왼쪽 마우스 버튼을 놓은 위치를 알려줍니다. 여기에서 DragOffset 을 빼 위젯을 드롭했을 때 어디에 놓을지를 결정합니다.

  6. Vector2D - Vector 2D 노드를 추가하고 Absolute to Local Return Value 에서 DragOffset 을 뺍니다.

    UpdateDragDrop1.1.png

  7. 우클릭하고 Remove from Parent , Add to Viewport , Set Position in Viewport 노드를 추가합니다. 모든 3 노드의 Exec 핀을 위 순서대로 연결하고, Set Position in Viewport 노드를 Return Node 에 연결합니다.

  8. 다음과 같이 연결하고 조정합니다:

    • Widget Reference 핀 > 모든 3 노드의 Target

    • Vector2D - Vector 2D 노드의 Return Value 핀 - Position

    • Remove DPIScale 해제

    • Return Value 체크

    UpdateDragDrop2.1.png

    Remove DPIScale 는 해제하고 Return Value 는 체크하는 이유는 DPI 스케일링 제거는 할 필요 없이 true 를 반환하도록 이 함수를 처리해 왔기 때문입니다. 이 스크립트를 통해, 먼저 기존 Health Bar 위젯을 제거한 뒤 화면의 Drag Offset 기준 새 위치에 다시 추가합니다.

  9. HUD 위젯 블루프린트를 컴파일 , 저장 합니다.

HUD 가 드래그중인 위젯 드롭을 처리하고 Health Bar 를 표시하도록 구성했습니다. 다음에는, Dragged Widget 을 Health Bar 모양과 비슷하게 구성하고 캐릭터 블루프린트에게 HUD 를 뷰포트에 추가하도록 할 것입니다.

4 - 드래그 위젯 스크립트

이번 단계에서는, 비주얼을 담당할 DragWidget 을 구성하겠습니다.

  1. DragWidget 위젯 블루프린트를 열고 Canvas Panel Size Box 로 대체하고 자손 Border 설정을 합니다.

  2. SizeBox 이름을 WidgetSize 로 변경하고 isVariable 을 true 로 설정한 뒤, Width Override Height Override 를 체크합니다.

    UpdateDragDrop3.png

    Size Box 의 Width 와 Height 를 Health Bar 위젯의 크기에 맞게 설정하도록 하겠습니다.

  3. Border 의 경우, Brush Color Black 으로, Alpha 0.5 로 하여 약간 반투명하게 만듭니다.

    UpdateDragDrop4.1.png

    이 예제에서 드래그 비주얼로는 Health Bar 의 실루엣을 사용하면서 실제 Health Bar 는 같은 위치에 유지합니다.

  4. 이벤트 그래프 에서, Event Construct 를 끌어 놓고 Cast to HealthBar 노드를 추가합니다. Widget Reference 를 끌어 놓고 Object 핀에 연결합니다.

  5. As Health Bar 핀에서 Get Desired Size 노드를 추가합니다. Return Value 핀을 Break Vector 2D 노드에 연결합니다.

    UpdateDragDrop5.png

    그러면 Size Box 에 설정할 수 있는 Health Bar 크기가 나옵니다. 오버라이드를 수동 입력할 수도 있지만, 그랬다면 Health Bar 크기 변경 시 여기서도 변경해 줘야 할 것입니다.

  6. 우클릭하고 Set Height Override Set Widget Override 노드를 추가하고 각각 Cast to HealthBar 노드에 연결합니다. 그런 다음 Widget Size 노드를 끌어 놓습니다.

  7. 다음과 같이 핀을 연결합니다.

    • Widget Size > Target

    • Break Vector 2D X > In Height Override

    • Break Vector 2D Y > In Width Override

    UpdateDragDrop6.png

  8. DragWidget 블루프린트를 컴파일 , 저장 합니다.

5 - HUD 위젯을 뷰포트에 추가

마지막으로, HUD 위젯 블루프린트를 Character 블루프린트의 뷰포트에 추가하고 Mouse Cursor 를 활성화하여 드래그 위치를 확인할 수 있도록 해야 합니다.

  1. 콘텐츠 브라우저 에서 Content/ThirdPersonBP/Blueprints 아래 ThirdPersonCharacter 블루프린트를 엽니다.

  2. Event Begin Play 노드에서 Create Widget 노드를 추가하고 Class HUD 로 설정합니다. Add to Viewport 노드를 생성하고 SET Show Mouse Cursor 에 연결합니다. Get Player Controller 노드를 추가하고 Return Value SET Target 에 연결합니다.

    DragDrop19.png

  3. 컴파일 , 저장 , 및 플레이 를 클릭하여 위젯을 드래그 앤 드롭합니다.

최종 결과

에디터에서 플레이 후, 화면에서 Health Bar 를 좌클릭 드래그 후 새 위치에 드롭합니다.

이는 드래그 앤 드롭 프로세스를 시작하는 데 필요한 엘리먼트 예제일 뿐입니다. 플레이어가 위젯을 세이프 존 외부 혹은 다른 위젯 위에 드래그하지는 않았나 추가적인 확인이 필요할 수 있습니다.

언리얼 엔진 문서의 미래를 함께 만들어주세요! 더 나은 서비스를 제공할 수 있도록 문서 사용에 대한 피드백을 주세요.
설문조사에 참여해 주세요
건너뛰기