Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Drag & Drop system: IDropHandler event not called?

Discussion in 'UGUI & TextMesh Pro' started by pixpusher2, Aug 25, 2014.

  1. pixpusher2

    pixpusher2

    Joined:
    Oct 30, 2013
    Posts:
    121
    Hi, I've took a look at the Drag & Drop example file and tried to implement the same for my inventory UI. But when I try combining some of the methods in DragMe.cs and DropMe.cs, the OnDrop() method of IDropHandler event is never called. What seems to be the issue?

    I combined the scripts because Ithe items are dragged from one inventory slot to another similar slot, so it needs to be both draggable and droppable, if that makes sense. Cheers

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4. using UnityEngine.UI;
    5. using System.Collections;
    6.  
    7. public class InventoryItemTracker : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IDropHandler
    8. {
    9.     public int slot = 0;
    10.  
    11.     public int GetSlot()
    12.     {
    13.         return this.slot;
    14.     }
    15.  
    16.     public void SetSlot(int index)
    17.     {
    18.         this.slot = index;
    19.     }
    20.  
    21.  
    22.     // DRAG
    23.     public void OnBeginDrag(PointerEventData eventData)
    24.     {
    25.         Debug.Log ("BEGIN DRAG");
    26.  
    27.         GUIManager.instance.InventoryDragItem(this.slot);
    28.  
    29.         GUIManager.instance.SetItemDragPlane(transform as RectTransform);
    30.  
    31.         // Update dragging Item position
    32.         GUIManager.instance.InventoryIsDraggingItem(eventData);
    33.     }
    34.  
    35.     public void OnDrag(PointerEventData data)
    36.     {
    37.         Debug.Log ("ON DRAG");
    38.  
    39.         // Update dragging Item position
    40.         GUIManager.instance.InventoryIsDraggingItem(data);
    41.     }
    42.  
    43.     public void OnEndDrag(PointerEventData eventData)
    44.     {
    45.         Debug.Log ("END DRAG");
    46.     }
    47.  
    48.     // DROP
    49.     public void OnDrop(PointerEventData data)
    50.     {
    51.         Debug.Log ("ON DROP");
    52.     }
    53. }
     
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,184
    Do you have a graphic on the target? The raycaster we use is based on graphics.
     
    lilinjie_ and charmi212121 like this.
  3. pixpusher2

    pixpusher2

    Joined:
    Oct 30, 2013
    Posts:
    121
    Thanks Tim. Apparently it was a silly mistake of mine.
    I forgot to add the IgnoreRaycast.cs script onto the dragging object when I replaced it with a prefab!

    Cheers
     
    Katori likes this.
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    This is good info - Thank you to both of you. Didn't catch the IgnoreRayCast part until I read this thread.

    Managed to boil down both drag and drop to rudimentary versions that are less than 10 lines both. I borrowed the IgnoreRayCast.cs part from example.

    I really don't understand exactly what part of Event System uses it? To what it passes it's data?

    This is how I used it:
    Add it in OnPointerDown, when start dragging an object (to dragged object).
    Remove it in OnEndDrag, when stop dragging.

    I suspect this: Raycast information "goes" to EventSystem itself, as manual states it "Manages Raycasting" and in this case Canvas object has Graphic Raycaster script... so when object I drag has IgnoreRayCast.cs component it puts out false and is ignored by GraphicRaycaster, and it's possible for EventSystem to see object under it? Manual is very short on information about this.

    Please clarify if possible - Thank you :)

    Hope there will be more simple examples later (after beta) !
     
    Last edited: Sep 1, 2014
  5. Too_Technical

    Too_Technical

    Joined:
    Aug 30, 2018
    Posts:
    1
    eses, the problem you're having seems to be a bit of confusion around what "drag" is.
    OnPointerDown registers the touch or mouse down input, not the start of a drag. It's useful for hold to click or something similar, but it doesn't tell the event system "hey, I started dragging, listen for a drop"

    The IDragHandler OnDrag(PointerEventData) will tell the event system "Hey, I'm dragging, listen for a drop"...
    Or maybe the IBeginDragHandler OnBeginDrag(PointerEventData)...

    I've been bashing my face against the event system all week, but I think that may solve your issue. It's not that the raycast doesn't see the OnDrop object, it just doesn't care because you didn't tell it you were dragging.

    Or maybe I just misunderstood what you were saying.

    Cheers

    Edit: Oops, necro'd a thread because it was one of the few I found in my searches. Hopefully it helps whoever stumbles here.
     
    danijel_protopixel likes this.
  6. SuperDuperStudios

    SuperDuperStudios

    Joined:
    Apr 10, 2018
    Posts:
    1
    Hi all ! My problem is kind of same but it is apparently working fine when i drag one instance and drop in on any other instance (Then OnDrop() is working). However if i drag an instance from any object and drop it on same dragged instance (Object from where i dragged it) then its OnDrop() method is not working, meanwhile its onPointerEnter() OnPointerExit() are working. I have two scripts on every object i-e DragMe and DropMe. Please help me out and save my life. Thanks in advance.
     
  7. TonyTerrific

    TonyTerrific

    Joined:
    Dec 3, 2019
    Posts:
    1
    A late addition to this thread for those still searching for an answer :D. I had the same problem in a 2D card game I've been working on, and after many hours have just worked it out. It was all to do with the thickness (collider Z scale) of the objects I was dragging/dropping and their Z transform position value. When dropping on an object I would re-parent that object to the container and set the transform position to that of the parent (using my own custom layout class) - at that point I was never able to drop it on another container. All I had to do when dragging was to bring the object closer to the camera (e.g. transform.position.z = -0.1f) and then all would work fine again. I also had to make sure all my containers were z = 0.01f to put them just back a little. Such a simple logic error but it's taken me hours to figure it out.

    I hope this helps some fellow traveler in future. :rolleyes:
     
  8. Plnda

    Plnda

    Joined:
    Nov 23, 2016
    Posts:
    12
    I spent hours figuring out why my onDrop wasn't called, it was because the IPointerDownHandler eats my drop event
     
    arham_kamal and ablemagic like this.
  9. arham_kamal

    arham_kamal

    Joined:
    Oct 11, 2020
    Posts:
    1
    Thanks Pinda !!
     
  10. Andrey-Postelzhuk

    Andrey-Postelzhuk

    Joined:
    Nov 26, 2013
    Posts:
    75
    This is my trick when dragging item blocks drop target:
    1. Disable dragging raycast target in OnBeginDrag.
    2. Enable dragging raycast target in OnEndDrag.
    3. OnDrag() will work anyway.
    4. Drop target object will get OnDrop event. Even it's behind in the hierarchy.

    Here is an example:
    Code (CSharp):
    1. public class DragItem : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
    2.     {
    3.         [SerializeField] protected Graphic _raycastTarget;
    4.         [SerializeField] protected RectTransform _itemTrans;
    5.        
    6.         public void OnDrag(PointerEventData eventData)
    7.         {
    8.             RectTransform parent = _itemTrans.parent as RectTransform;
    9.             bool success =
    10.                 RectTransformUtility.ScreenPointToLocalPointInRectangle(
    11.                     parent,
    12.                     eventData.position,
    13.                     eventData.enterEventCamera,
    14.                     out Vector2 locPos);
    15.  
    16.             if (success)
    17.             {
    18.                 _itemTrans.anchoredPosition = locPos;
    19.             }
    20.         }
    21.  
    22.         public void OnBeginDrag(PointerEventData eventData)
    23.         {
    24.             _raycastTarget.raycastTarget = false;
    25.         }
    26.  
    27.         public void OnEndDrag(PointerEventData eventData)
    28.         {
    29.             _raycastTarget.raycastTarget = true;
    30.         }
    31.     }