[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 구성을 기대하며… 🙂