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 are updating our Terms of Service for all Unity subscription plans, effective October 13, 2022, to create a more streamlined, user-friendly set of terms. Please review them here: unity.com/legal/terms-of-service.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Obtaining GameObject from PointerEventData when OnEndDrag is triggered

Discussion in 'Scripting' started by xanat0s, Mar 11, 2015.

  1. xanat0s

    xanat0s

    Joined:
    Nov 20, 2014
    Posts:
    10
    As the title indicates, I'm looking to obtain an arbitrary GameObject that the pointer is currently hovering over during the end of a drag event. PointerEventData holds several fields, one of which is the pointerDrag field, but that field only holds a reference to the GameObject that was being hovered over during the beginning of a drag event.

    I don't really understand why the reference in pointerDrag never changes during a drag event. The field itself is rather unhelpful when the reference it holds is really only applicable when the drag event begins. (The pointer is being dragged after all, it stands to reason that the underlying game object is going to change during the course of a drag action.)

    Are there any suggestions as to how I can achieve the functionality I'm looking for? I dug through the UnityEngine.EventSystems in hopes of determining how the object reference is being obtained to begin with, but haven't had much luck.
     
  2. edwinschrauwen

    edwinschrauwen

    Joined:
    Mar 10, 2015
    Posts:
    19
    According to the documentation, PointerEventData has a property pointerEnter, which is described as "The object that received 'OnPointerEnter'". Maybe that's what you're looking for?

    As I understand it, and take this with a pinch of salt as I've used Unity for the first time just yesterday, pointerDrag does not change value because it refers to the object you started dragging from. The documentation states "The object that is receiving 'OnDrag'".

    It would seem to me though that it would make more sense to go about this the other way around, i.e. check for the hover on the receiving end, rather than on the sending one. Not at all sure about this though, perhaps someone else could shed some light..?
     
    kdualpha_unity likes this.
  3. xanat0s

    xanat0s

    Joined:
    Nov 20, 2014
    Posts:
    10
    Thanks for your input. So I've been doing some testing today, taking your suggestion into consideration, and it appears that pointerEnter may be sufficient to achieve the results I'm looking for. (My scene essentially consists of a complex 2D UI framework, with lots of overlapping objects.) Though, pointerEnter seems to grab the bottom-most child in the hierarchy. E.g. if the pointer is hovering over a button, it will grab a reference to the button's text object, whereas pointerDrag obtains a reference to the button itself. Not sure if there's actually a reason for that behavior, but it's easy enough to remedy. I should be able to travel up the hierarchy when needed via obj.transform.parent.
     
    aseaboyer likes this.
  4. steveh2112

    steveh2112

    Joined:
    Aug 30, 2015
    Posts:
    246
    i was able to find the parent object like this, maybe no the best way but it works

    public void OnPointerEnter(PointerEventData eventData)
    {
    Debug.Log ("SliderWheel: OnPointerEnter="+eventData.pointerEnter.transform.parent.name);
    Debug.Log ("SliderWheel: OnPointerEnter="+eventData.pointerEnter.transform.parent.parent.name);
    if(eventData.pointerEnter.transform.parent.tag=="Slider")
    activeSlider = GameObject.Find(eventData.pointerEnter.transform.parent.name).GetComponent<Slider>();
    else if(eventData.pointerEnter.transform.parent.parent.tag=="Slider")
    activeSlider = GameObject.Find(eventData.pointerEnter.transform.parent.parent.name).GetComponent<Slider>();
    }
     
  5. Aithoneku

    Aithoneku

    Joined:
    Dec 16, 2013
    Posts:
    67
    It might be little too late, but I was just solving same problem.

    First, we use Unity 5.3.4f1, so the behavior might be different from newest Unity.

    The most logical variable to use would be PointerEventData.hovered - it's list of Game Objects, hierarchy of what's under the mouse. Most of the time, fist element is game object deepest in hierarchy (the one which is actually hovered). Problem is that when I move mouse quickly, the list gets shuffled a bit.

    My solution

    Thing which works to me is PointerEventData.pointerCurrentRaycast.gameObject - that's the game object right under the mouse and that's what I use.

    There is a catch, however. Logically, under the mouse is usually object being dragged. This can be solved by attaching CanvasGroup and setting CanvasGroup.blocksRaycasts = false during dragging so it becomes „transparent“ for hover checks. (It should be reverted back to true when dragging stops.)
     
    Eklofakka likes this.
  6. Tsilliev

    Tsilliev

    Joined:
    Jan 21, 2014
    Posts:
    34
    When your object is dragging make its layer "draggable", and after dragging revert to original.
    Before you start your scene go to your camera's physics/graphics raycast and at the blocking/event mask instead of everything disable layer "draggable". Voila, your pointer events will detect the objects normally like before dragging even while dragging.
     
  7. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
    Just for the record, you can disable raycasting on text elements, so the pointer should not hit the textfield of a button but the button itself.
     
unityunity