Skip to content

Instantly share code, notes, and snippets.

@phosphoer
Last active November 27, 2023 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phosphoer/1dfa933a480a2a6170cd4a7c83cd3173 to your computer and use it in GitHub Desktop.
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.
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