Hey guys, I tried searching for this but I haven’t really found what I am looking for.
Basically, DragAndDrop seems to be the class that would handle the functionality for dragging and dropping objects into and out of a custom editor window, but it may just be for dropping out of, not sure yet.
What I am trying to do is create a custom editor window where you can drag and drop multiple assets from the Project View onto a specific rect (or region) inside of my custom editor window. Obviously once that’s done, it should give me an array or generic of the objects I dragged into the area so I can then manipulate the data however I want.
That’s a little tricky. Gui buttons operate on mouse button UP, not down, so you’ll have to do your own thing. My solution is to keep track of my own gui buttons, creating every one with a rect: http://unity3d.com/support/documentation/ScriptReference/Rect.Rect.html
to make a gui box (not button):
I check for an event:
of type Mouse Down:
check to see if the mouse position is in the rectangle of your button when it’s clicked:
and if so, then instantiate the object at the mouse position. I use Raycast to find out where the mouse is in world space:
and I keep the object there until the MouseUp event and that’s it.
Would that work with EditorWindow? I am trying to drag something from the Project View to a custom editor window, not the Scene per se. That looks like something that would come in handy if I were dropping in assets and trying to place them with a snap or something, like an RTS.
DragAndDrop is indeed the class you use to handle any dragging and dropping. Here’s a bit of code I did;
using UnityEngine;
using UnityEditor;
using System.Collections;
public class SpriteManager : EditorWindow {
public Texture2D[] sprites;
[MenuItem("Window/Sprite Manager")]
static void Init () {
EditorWindow.GetWindow(typeof(SpriteManager));
}
void OnGUI () {
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
if (Event.current.type == EventType.DragExited) {
sprites = new Texture2D[DragAndDrop.objectReferences.Length];
for (int i = 0; i < DragAndDrop.objectReferences.Length; i++) {
sprites[i] = DragAndDrop.objectReferences[i] as Texture2D;
}
}
}
}
It’s as simple as using DragAndDrop.objectReferences, which is a generic with all of the different objects you are dragging. At least now I figured out that part, now i have to figure out how to get that data at runtime and save it across sessions.
I’m doing a very similar thing here and I’ve found DragAndDrop to be the solution. In my situation I’m allowing the user to drag a Texture2D from the project folder into a custom EditorWindow at which point I’d like to find the mousePosition within the EditorWindow so that I can generate an EZ GUI button GameObject and populate that button with the texture. (I’m working on an EZ GUI Editor)
Now I’ve solved this problem except for one issue. When I try to grab the mousePosition it’s not correct. It basically doesn’t seem to be updating mousePosition based on the current EditorWindow that has focus. This is an issue because it makes generating the GameObject at the correct 3d position impossible because I need mousePosition to be in the context of the EditorWindow’s screen space. Is there any way to do this? I haven’t found a good way to switch mousePosition’s context.
if (Event.current.type == EventType.DragExited)
{
Debug.Log("DragExit event, mousePos:" + Event.current.mousePosition + "window pos:" + position);
foreach (Object obj in DragAndDrop.objectReferences)
{
if (obj.GetType() == typeof(Texture2D))
_currentUI.CreateUIButton(((Texture2D)obj).width, ((Texture2D)obj).height, GetWorldPoint(Event.current.mousePosition));
}
}
I ended up finding a solution by just flipping a bit to true when the DragExited event occurs and then I wait to actually execute the drag inport until I get the next repaint event because by then the mousePosition seems to be back in the EditorWindow’s context.
public static object[] DropZone(string title, int w, int h){
GUILayout.Box(title, GUILayout.Width(w), GUILayout.Height(h));
EventType eventType = Event.current.type;
bool isAccepted = false;
if (eventType == EventType.DragUpdated || eventType == EventType.DragPerform){
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (eventType == EventType.DragPerform) {
DragAndDrop.AcceptDrag();
isAccepted = true;
}
Event.current.Use();
}
return isAccepted ? DragAndDrop.objectReferences : null;
}
basically it create a dropzone where you can drop things like folder, textures … and return the list of thing dropped, you can then filter to have the things you want.