Last active
November 27, 2023 20:47
-
-
Save phosphoer/1dfa933a480a2a6170cd4a7c83cd3173 to your computer and use it in GitHub Desktop.
A drag and droppable 'scratchpad' for unity objects, useful as a palette or a quick select window.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
using System.Collections.Generic; | |
public class AssetScratchpad : EditorWindow | |
{ | |
private List<Object> _referenceList = new(); | |
private Vector2 _scrollPosition; | |
[MenuItem("Window/Asset Scratchpad")] | |
public static void ShowWindow() | |
{ | |
EditorWindow.GetWindow<AssetScratchpad>("Asset Scratchpad"); | |
} | |
private void OnGUI() | |
{ | |
// Draw drop area | |
Rect dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true)); | |
var styleBox = new GUIStyle(GUI.skin.box); | |
styleBox.normal.textColor = Color.white; | |
styleBox.hover.textColor = Color.white; | |
styleBox.alignment = TextAnchor.MiddleCenter; | |
GUI.Box(dropArea, "Drop objects here", styleBox); | |
// Clear button | |
if (GUI.Button(new Rect(0, 0, 80, 20), "Clear")) | |
{ | |
_referenceList.Clear(); | |
} | |
// Contain list in a scrollview | |
_scrollPosition = GUILayout.BeginScrollView(_scrollPosition); | |
for (int i = 0; i < _referenceList.Count; i++) | |
{ | |
if (_referenceList[i] == null) | |
{ | |
_referenceList.RemoveAt(i); | |
continue; | |
} | |
EditorGUILayout.BeginHorizontal(); | |
DrawDraggableObjectField(_referenceList[i], i); | |
if (GUILayout.Button("Remove", GUILayout.MaxWidth(80))) | |
{ | |
_referenceList.RemoveAt(i); | |
} | |
EditorGUILayout.EndHorizontal(); | |
} | |
GUILayout.EndScrollView(); | |
// Handle events | |
Event evt = Event.current; | |
switch (evt.type) | |
{ | |
case EventType.DragUpdated: | |
case EventType.DragPerform: | |
DragAndDrop.visualMode = DragAndDropVisualMode.Copy; | |
if (evt.type == EventType.DragPerform) | |
{ | |
DragAndDrop.AcceptDrag(); | |
foreach (Object obj in DragAndDrop.objectReferences) | |
{ | |
if (!_referenceList.Contains(obj)) | |
_referenceList.Add(obj); | |
} | |
} | |
Event.current.Use(); | |
break; | |
} | |
} | |
private void DrawDraggableObjectField(Object obj, int index) | |
{ | |
Rect rect = GUILayoutUtility.GetRect(0, EditorGUIUtility.singleLineHeight); | |
// Get the content (icon and text) for the object | |
GUIContent content = EditorGUIUtility.ObjectContent(obj, typeof(Object)); | |
// Draw the icon | |
GUI.Label(new Rect(rect.x, rect.y + 2, 20, EditorGUIUtility.singleLineHeight), content.image); | |
// Draw the object field | |
EditorGUI.LabelField(new Rect(rect.x + 25, rect.y + 2, rect.width - 25, EditorGUIUtility.singleLineHeight), | |
new GUIContent(obj.name, "Drag to another field"), EditorStyles.objectField); | |
Event evt = Event.current; | |
switch (evt.type) | |
{ | |
// Allow dragging from field | |
case EventType.MouseDrag: | |
if (rect.Contains(evt.mousePosition)) | |
{ | |
DragAndDrop.PrepareStartDrag(); | |
DragAndDrop.objectReferences = new Object[] { obj }; | |
DragAndDrop.StartDrag(obj.name); | |
Event.current.Use(); | |
} | |
break; | |
// Ping objects on click | |
case EventType.MouseUp: | |
if (rect.Contains(evt.mousePosition) && evt.button == 0) | |
{ | |
EditorGUIUtility.PingObject(obj); | |
} | |
else if (rect.Contains(evt.mousePosition) && evt.button == 1) | |
{ | |
EditorUtility.OpenPropertyEditor(obj); | |
} | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment