[Unity] 에디터 프로그래밍 – Drag and Drop UI 구현

에디터 윈도우를 하나 띄워보고, 프리팹을 드래그 앤 드랍하여 해당 오브젝트를 사용해보자.  우선 BEditorWindow.cs 스크립트를 만들고, OnEnable, OnDisable, OnGUI 함수를 추가하였다.  

파일을 드래그하여 놓을 위치는 GUI.Box를 이용하여 영역을 잡아보았다.

using UnityEngine;
using UnityEditor;
public class BEditorWindow : EditorWindow
{
    [MenuItem("Tools/DragNDropWindow")]
    static void Init()
    {
        EditorWindow.GetWindow(typeof(BEditorWindow)).Show();
    }
    protected void OnEnable()
    {
    }
    protected void OnDisable()
    {
    }
    private void OnGUI()
    {
        var dropArea = GUILayoutUtility.GetRect(100, 100);
        GUI.Box(dropArea, "Drag and Drop");
    }
}

컴파일이 잘 되었다면, 아래와 같이 박스영역이 UI상에 표시될 것이다. (메뉴 Tools/DragNDropWindow 실행)

박스 영역에 대하여 마우스 드래그 이벤트가 일어나는지를 체크하고, 마우스 버튼을 땠을 때 드래그한 오브젝트에 대한 정보를 가져와보자.

private void OnGUI()
    {
        var dropArea = GUILayoutUtility.GetRect(100, 100);
        GUI.Box(dropArea, "Drag and Drop");

        var evt = Event.current;      //현재 이벤트 얻어오기.
        switch (evt.type)
        {
            case EventType.DragUpdated:     // 드래그 하는 동안 업데이트 되는 이벤트 타입.
            case EventType.DragPerform:    // 드래그 후 마우스 버튼 업인 상태일때.
                {
                    if (!dropArea.Contains(evt.mousePosition))    // 마우스 포지션이 박스안에 영역인지 확인.
                        break;
                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
                    if (evt.type == EventType.DragPerform)   // // 드래그 후 마우스 버튼 업인 상태일때.
                    {
                        DragAndDrop.AcceptDrag();   // 드래그앤 드랍을 허용함.
                        foreach (var draggedObj in DragAndDrop.objectReferences)    // objectReferences: 드래그한 오브젝트들의 레퍼런스
                        {
                            var go = draggedObj as GameObject;
                            if (!go)
                                continue;
                            EditorUtility.DisplayDialog("Message", go.name, "ok");
                        }
                    }
                }
                Event.current.Use();  // 이벤트 사용한 후, 이벤트의 타입을 변경해준다. (EventType.Used)
                break;
        }
    }

약간 복잡해 보이긴 하지만, 커멘트한 내용을 살펴보면 어떻게 진행되는지 흐름을 알 수 있다.

현재 이벤트를 얻어오고, 드래그후 마우스 버튼이 업인 상태일 때, 마우스 포지션을 확인하여 미리 정의한 박스 영역에 있는지 확인하고, 그 작업을 허용하게 되면, 드레그한 오브젝트의 레퍼런스를 접근 할 수 있게 된다.  

MyCube.prefab을 만들고, 그 프리팹을 드레그하여 에디터 윈도우안 박스위에 놓은 후, 이름이 팝업에 나오도록 해보았다.

테스트를 해보면, 드래그한 프리팹의 이름이 팝업으로 노출이 잘 될 것이다.

이제 드래그한 오브젝트의 레퍼런스를 이용하여, Scene에 인스턴스 객체를 생성해보자.

 private void OnGUI()
    {
        var dropArea = GUILayoutUtility.GetRect(100, 100);
        GUI.Box(dropArea, "Drag and Drop");
        var evt = Event.current;      //현재 이벤트 얻어오기.
        switch (evt.type)
        {
            case EventType.DragUpdated:     // 드래그 하는 동안 업데이트 되는 이벤트 타입.
            case EventType.DragPerform:    // 드래그 후 마우스 버튼 업인 상태일때.
                {
                    if (!dropArea.Contains(evt.mousePosition))    // 마우스 포지션이 박스안에 영역인지 확인.
                        break;
                    DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
                    if (evt.type == EventType.DragPerform)   // // 드래그 후 마우스 버튼 업인 상태일때.
                    {
                        DragAndDrop.AcceptDrag();   // 드래그앤 드랍을 허용함.
                        foreach (var draggedObj in DragAndDrop.objectReferences)    // objectReferences: 드래그한 오브젝트들의 레퍼런스
                        {
                            var go = draggedObj as GameObject;
                            if (!go)
                                continue;
                            //EditorUtility.DisplayDialog("Message", go.name, "ok");
                            Instantiate(go);  //객체 생성
                        }
                    }
                }
                Event.current.Use();  // 이벤트 사용한 후, 이벤트의 타입을 변경해준다. (EventType.Used)
                break;
        }
    }

MyCube.prefab을 드래그하여 드랍해보면, Scene뷰상의 원점에 큐브 오브젝트가 하나 생성되었을 것이다.

여기까지 잘 되었다면, 이제 드래그 앤 드랍을 용도에 맞게 사용면 된다. 좀 더 편리하고 유연한 UI 구성을 기대하며… 🙂  끝.



Leave a Reply

Your email address will not be published. Required fields are marked *