These days it's incredibly easy to drag UI elements in Unity: Make a few UI items. Add Component -> Event -> Event Trigger. Drop on the script below. Click to add the four obvious triggers. You're done.
However.
I'm totally lost in the relationship between pointer coordinates and UI coordinates (as seen in RectTransform and so on).
In DragIt
below: how the hell do you move a UI panel correctly under the finger?
Say you have one large panel, with ten UIButton sitting in the panel with Dragster
on the buttons. What is the relationship between the RectTransform coords and the mouse pointer ...
in short how do you move one of the button around at DragIt() below?
/* modern Unity drag of UI element */
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
public class Dragster:MonoBehaviour
{
public int index; // number each of your UI items
static bool beingDragged = false;
static int dragFrom;
public void DragStart()
{
beingDragged = true; dragFrom = index;
}
public void DragIt()
{
? ? W T F ? ?
}
public void DragEnd()
{
beingDragged = false;
}
public void DroppedBra()
{
Debig.Log("Drag: from/to " +dragFrom +" --> " +index);
}
}
First of all, All the other anwers in this post are working very well. I worked on this for so long and just wanted to post it here. It adds a way prevent other unwanted UI objects to be dragged around.
My official goal was to provide a way to do this without using
bool beingDragged = false;
. You just won't know whichButton
orImage
is being dragged if you do it like that.Dragging UI:
Convert Screenpoint to Local point in the RectTransform with help of
RectTransformUtility
then useCanvas.transform.TransformPoint
to find out where exactly the child UI is.The drag code looks more complicated than other drag code in other answers but it seems to be working in every Canvas camera mode.
Detecting which Object is about to be dragged:
The easiest way of doing this is to create a global variable you can use to save which object user wants to drag in the
OnBeginDrag
function then you can drag that object in theOnDrag
. Set that object to null whenOnEndDrag
is called.This must be done once in the
OnBeginDrag
function then saved to a global variable.You can't do the following in the
OnDrag
functionEven though it is suppose to work, it doesn't sometimes. It even return null sometimes during
OnDrag
. That's why it has to be done in theOnBeginDrag
function.Detecting and Dragging Button Vs Image:
Detecting if the UI is just an
Image
and Dragging anImage
is very easy.If
tempImage
is notnull
andtempButton
isnull
then that is an Image.Detecting if the UI is just a
Button
and Dragging aButton
is NOT easy. When a Button is clicked on the side/edge, the name of theButton
is returned which is fine. But most of the times, a click on aButton
happens in the middle of theButton
which does not return the instance or name of the Button but instead returns theText
(Child Object). You CANNOT move a text as a Button. It wont work.if
tempText
is not null, getGetComponentInParent
of Image and Button component of the Text. If theImage
is not null andButton
is not null then it is aButton
.Below is the complete script of dragging UI Image/Panel and Button. Any Button that should be dragged should be put in the
UIButtons
array and any Panel/Image that should be dragged should be put in theUIPanels
array. It will ignore other UI that are not in the Array.I would make your script implement the drag interfaces
public class Dragster:MonoBehaviour,IBeginDragHandler, IEndDragHandler, IDragHandler
Which will make your
DragIt
function becomegiving you access to the delta of that event (how much the mouse has moved) to be able to move your object.
If you would still rather use the EventTrigger component (less prefered way), you just need to change your
DragIt
function toDragIt(PointerEventData eventData)
and use the Dynamic EvenData option in the drop down for the trigger to receive the PointerEventData to access the delta informationHere's actually a total, complete, solution for drag and drop 'UnityEngine.UI` items, based on Uri & Colton's code. Just copy and paste.
Astounding copy and paste no-brainer perfect drag and drop for Unity UI, wtt Colton & Uri:
For Draging stuff I just do this :