Editor DragAndDrop bug - system needs to be initialized by Unity?

Hey guys, I am have major issues with the DragAndDrop class in Unity.

I submitted a bug report and just incase it is my fault, I thought I’d ask around here!

It seems that, internally, the DragAndDrop thing has some sort of initialization that needs to be performed, and this initialization is performed on the first drag/drop operation performed since you opened up Unity.

Problem is, when you want to use DragAndDrop between two custom editor windows, the intialisation isnt performed. The 2nd window does not recieve DragUpdate and DragPerformed events, only DragExit, and so it cannot react to the drag.

Fixing the issue is easy - you simply perform a drag/drop opertion inside any native Unity window, and now you can drag and drop between 2 editor windows.

This is a huge issue for me, the tool I am working on has something similar to the Project view and the Scene view, so the user must be able to drag objects from the ‘project’ into the ‘scene’. This is only possible if the user performs the drag and drop work around outlined above, and I cant ask my users to do that.

I am hoping that there is something I can do to manually start up the drag/drop. Maybe I am doing it wrong?

Here is a clean repo, minimal code, check it out (Clicky)!

I’m afraid it’s you and not Unity. I got a panel (basically rewrote the Hierarchy window) that support drag and drops. And as soon as I open Unity, it works fine, without any previous drag and drop.

What I did noticed while making it is, you can actually corrupt the internal drag and drop object. The only solution I found once it was corrupted was to perform a drag in a native window. Now… I don’t actually remember what was the error I did that actually corrupted it in the first place. Just that I managed to fix it at some point.

The documentation is lacking when it comes to drag drop - I pretty much copied whatever I found and used that. Did you download and check the repo? Below is the code, its very simple and I dont see where it could corrupt. It is also curious that, without fail, (on my machine anyway) drag and drop will not work unless I do a drag and drop inside a native window… Are you performing drag/drop between 2 custom EditorWindows? Or between a custom window->native window or native window->custom window?

This is how we initiate the Drag

if (Event.current.type == EventType.mouseDrag  new Rect(0,0,position.width,position.height).Contains(Event.current.mousePosition))
		{
			if(DragAndDrop.objectReferences.Length == 0)
			{
				DragAndDrop.PrepareStartDrag();
                DragAndDrop.SetGenericData("currentValue", 50.0f);
				DragAndDrop.StartDrag("Drag current value");
				Event.current.Use();
			}
		}

and this is how we recieve it:

        if (Event.current.type == EventType.dragUpdated || Event.current.type == EventType.dragPerform)
        {
            if (new Rect(0,0,position.width,position.height).Contains(Event.current.mousePosition))
            {
                float? b = DragAndDrop.GetGenericData("currentValue") as float?;
                if (b.HasValue)
                {
                    DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                    if (Event.current.type == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();
                        Event.current.Use();
                        Debug.Log(b.GetValueOrDefault());
                    }
                }
            }
        }

which just log’s 50 if the drag and drop works as expect from one window to another.

I will honestly be over the moon if it is something I am doing wrong, but the code above is pretty basic stuff. I dont see where I could have stuffed up.

Furthermore, printing all Event.current.type’s for the receiving window shows that EventType.dragUpdated and EventType.dragPerform never actually happen. Not until I do a drag and drop inside a native Unity window. After that everything works, without fail, until I close Unity. No other corrupts after the first native drag/drop, never. I have been working on my tool all day and not a single problem with it, as long as I perform the work around

sorry for sounding a little upset, I have been stuck on this since Monday, and my only work around right now is to rework the tools workflow and how objects are passed between windows, which I do not want to do. I really want to believe its my fault right now, but I can’t see anything wrong and the evidance (on my end, anyway) points to another cause.

I am redownloading Unity and will do a fresh install and see if the error persists on the latest version for me. :rage:

Same issue, 4.3.2f1

Ah! I see, not the same issue I had. However, it “feels” somewhat similar.

Let’s see…

I did

public class DragDropWrapper
{
    private object value;

    public object Value
    {
        get { return value; }
    }

    public DragDropWrapper(object value)
    {
        this.value = value;
    }
}

and in your DragWindow;

if (Event.current.type == EventType.mouseDrag)
{
    if (DragAndDrop.objectReferences.Length == 0)
    {
        DragAndDrop.PrepareStartDrag();
        DragAndDrop.objectReferences = new Object[] { null };
        DragAndDrop.SetGenericData("currentValue", new DragDropWrapper(currentValue));
        DragAndDrop.StartDrag("Drag current value");
        Event.current.Use();
    }
}

and finally in your DropWindow;

if (Event.current.type == EventType.dragUpdated || Event.current.type == EventType.dragPerform)
{
    DragDropWrapper wrapper = DragAndDrop.GetGenericData("currentValue") as DragDropWrapper;

    if (wrapper != null)
        DragAndDrop.visualMode = DragAndDropVisualMode.Link;

    if (Event.current.type == EventType.DragPerform)
    {
        DragAndDrop.AcceptDrag();
        Event.current.Use();
        currentValue = (float)wrapper.Value;
    }
}

And now it works 100%. Or at least, I can’t repro your bug anymore on 4.2.2.

Frankly, I don’t remember why I ended up using a wrapper class when passing data by drag and drop. Maybe it was the issue I encountered with corrupted internal data. Maybe not. However, since I did use a wrapper around any Value type, I decided to try it on your example, and surprise, it worked. Now don’t ask me why; that, I could not answer.

Oh, I also set a “new object[ ] { null }” in the objectReferences fields. Maybe it has something to do with it. Sorry… 3 AM.

Oh my goodness gracious, it works. I am so very happy that you chose tonight of all nights to sit up till 3AM, thanks and merry christmas :hushed:

Just a quick note. The issue I faced back then was that when the DragAndDrop was messed up, Unity stopped firing the DragUpdate and DragPerform Event in the different EditorWindow. It looks like you got the same issue, but from an different setup. After a full night of sleep, my brain processed that it was probably a none-initialized “objectReferences” that messed things up.

Just to test up, I retook your original version and only added the line;

DragAndDrop.objectReferences = new Object[] { null };

and now it works. So my guess is, Unity at some point try to test or to marshal “objectReferences” and get an invalid pointer, and someone forget to throw an exception when that happen.

1 Like

Thanks a lot for the fix. I was getting mad with this problem in 4.3.4f1. My code seemed to be right. In my case what i did to solve it was:

DragAndDrop.objectReferences = new UnityEngine.Object[0];

Instead of your snippet. Otherwise I would get null reference exceptions when dragging over the hierarchywindow from my panel.