Search Unity

Problem with dragging

Discussion in 'Scripting' started by Mr_Benn, Jun 19, 2019.

  1. Mr_Benn

    Mr_Benn

    Joined:
    Feb 14, 2019
    Posts:
    25
    Hi

    I created a UI canvas with some UI child elements on it. The dimensions of the canvas are 1600 x 800, with 0 in the centre.

    I have been trying to learn how to use the IDragHandler interface to drag some UI elements around on the canvas. However, I have a problem that I don't understand. The x y recttransform values of the UI Image to be dragged might start out at -500, -200, for example, but as soon as I try to drag the element, its x y values in the rect transfrom sky rocket to five figures and it disappears off canvas somewhere.

    All I'm doing on the dragged object is this:

    Code (CSharp):
    1. public class ItemDragHandler : MonoBehaviour, IDragHandler
    2. {
    3.     public void OnDrag(PointerEventData eventData)
    4.     {
    5.         transform.position = Input.mousePosition;
    6.     }
    7. }
    What might I be doing wrong?
    Cheers
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    You need to also implement IBeginDragHandler and IEndDragHandler.

    Unity ignores your drag handler unless you also implement those. They don't have to actually DO anything, but you need to have them.

    (Your confusion is perfectly reasonable; this is a stupid and misleading way for Unity to have organized things, and they don't even warn you in the documentation. It's just a magical thing you have to know.)
     
    SparrowGS likes this.
  3. Mr_Benn

    Mr_Benn

    Joined:
    Feb 14, 2019
    Posts:
    25
    Thanks. I've added the interfaces but it behaves exactly the same. Also, what do you put in onBegin and OnEnd? I don't need anything special to happen here...

    Code (CSharp):
    1. public class ItemDragHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    2. {
    3.     public void OnBeginDrag(PointerEventData eventData)
    4.     {
    5.         //transform.position = ;
    6.     }
    7.  
    8.     public void OnDrag(PointerEventData eventData)
    9.     {
    10.         transform.position = Input.mousePosition;
    11.     }
    12.  
    13.     public void OnEndDrag(PointerEventData eventData)
    14.     {
    15.         //transform.position = ;
    16.     }
    17. }
     
  4. Team2Studio

    Team2Studio

    Joined:
    Sep 23, 2015
    Posts:
    98
    I think you need to use RectTransform instead of transform
     
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    It looks to me like that code should do something, so I'm not sure what might be stopping it. I'd try adding a Debug.Log statement to check whether OnDrag is running at all.

    However, note that the coordinate system for the mousePosition is in pixels rather than Unity game units, so that code won't necessarily make the game object follow the mouse in the way you are probably expecting.

    This page includes an example of how to make an object follow the cursor while you are dragging.

    Alternately, here's some code I wrote (based on the above) for dragging a UI object in my game:

    Code (CSharp):
    1.     private bool dragging = false;
    2.     private Vector3 dragOffset;
    3.  
    4.     public void OnBeginDrag(PointerEventData eventData)
    5.     {
    6.         if (eventData.button != PointerEventData.InputButton.Left) return;
    7.         dragging = true;
    8.         Vector3 worldpoint;
    9.         if (DragWorldPoint(eventData, out worldpoint))
    10.         {
    11.             dragOffset = GetComponent<RectTransform>().position - worldpoint;
    12.         }
    13.         else
    14.         {
    15.             dragOffset = Vector3.zero;
    16.         }
    17.     }
    18.     public void OnEndDrag(PointerEventData eventData)
    19.     {
    20.         if (eventData.button != PointerEventData.InputButton.Left) return;
    21.         dragging = false;
    22.     }
    23.     public void OnDrag(PointerEventData eventData)
    24.     {
    25.         if (eventData.button != PointerEventData.InputButton.Left) return;
    26.  
    27.         Vector3 worldpoint;
    28.         if (DragWorldPoint(eventData, out worldpoint))
    29.         {
    30.             RectTransform rt = GetComponent<RectTransform>();
    31.             rt.position = worldpoint + dragOffset;
    32.         }
    33.     }
    34.  
    35.     // Gets the point in worldspace corresponding to where the mouse is
    36.     private bool DragWorldPoint(PointerEventData eventData, out Vector3 worldPoint)
    37.     {
    38.         return RectTransformUtility.ScreenPointToWorldPointInRectangle(
    39.             GetComponent<RectTransform>(),
    40.             eventData.position,
    41.             eventData.pressEventCamera,
    42.             out worldPoint);
    43.     }
    44.  
     
    Futurristic likes this.