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);
}
}
I would make your script implement the drag interfaces
public class Dragster:MonoBehaviour,IBeginDragHandler, IEndDragHandler, IDragHandler
Which will make your DragIt
function become
public void OnDrag(PointerEventData eventData)
{
transform.position += (Vector3)eventData.delta;
}
giving 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 to DragIt(PointerEventData eventData)
and use the Dynamic EvenData option in the drop down for the trigger to receive the PointerEventData to access the delta information
Here's actually a total, complete, solution for drag and drop 'UnityEngine.UI` items, based on Uri & Colton's code. Just copy and paste.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class UNCDraggable:MonoBehaviour,
IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler
{
public Image ghost;
// note DON'T try to drag the actual item: it's not worth the hassle.
// a problem arises where you can't have it on top (as you would want
// visually), and still easily get the drops. always use a ghost.
// even if you want the "original invisible" while dragging,
// simply hide it and use a ghost. everything is tremendously
// easier if you do not move the originals.
void Awake()
{
ghost.raycastTarget = false;
// (just in case you forgot to do that in the Editor)
ghost.enabled = false;
}
public void OnBeginDrag(PointerEventData eventData)
{
ghost.transform.position = transform.position;
ghost.enabled = true;
}
public void OnDrag(PointerEventData eventData)
{
ghost.transform.position += (Vector3)eventData.delta;
}
public void OnEndDrag(PointerEventData eventData)
{
ghost.enabled = false;
}
public void OnDrop(PointerEventData data)
{
GameObject fromItem = data.pointerDrag;
if (data.pointerDrag == null) return; // (will never happen)
UNCDraggable d = fromItem.GetComponent<UNCDraggable>();
if (d == null)
{
// means something unrelated to our system was dragged from.
// for example, just an unrelated scrolling area, etc.
// simply completely ignore these.
return;
// note, if very unusually you have more than one "system"
// of UNCDraggable items on the same screen, be careful to
// distinguish them! Example solution, check parents are same.
}
Debug.Log ("dropped " + fromItem.name +" onto " +gameObject.name);
// your code would look probably like this:
YourThings fromThing = fromItem.GetComponent<YourButtons>().info;
YourThings untoThing = gameObject.GetComponent<YourButtons>().info;
yourBossyObject.dragHappenedFromTo(fromThing, untoThing);
}
}