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. Dismiss Notice

ScrollRect and OnPointerDown is broken.

Discussion in 'UGUI & TextMesh Pro' started by siege911, Sep 6, 2014.

  1. siege911

    siege911

    Joined:
    Sep 30, 2011
    Posts:
    3
    I'm trying to create a list of players that can be re-ordered. I was using the basic ScrollRect to get the basic scrolling for the list if it goes off the screen. Then on the right side of the player there is a Button that if you click and hold, it will move the player up or down to be able to reorder the list of players. I'm using OnPointerDown to trigger that. Unfortunately, it seems that if the Button is a child of the ScrollRect, the OnPointerDown triggers properly but as soon as I move my mouse, the OnPointerUp triggers as well. I've only tested it with the mouse but if my Button is outside the ScrollRect, it works perfectly (albeit without the ScrollRect functionality I want). Inside the ScrollRect, it's broken. I've even tried programmably removing and re-adding the ScrollRect Component and it still doesn't work.

    Any suggestions on a workaround or is this a bug?

    Here's some sample code I started on.
    Code (CSharp):
    1.     void Update () {
    2.         if (startClick) {
    3.  
    4.             float mousePosOffset = mouseStartPos.y - Input.mousePosition.y;
    5.             float listItemOffset = listItemStartPos.y - mousePosOffset;
    6.  
    7.             Vector3 tempPos = new Vector3(parentTransform.position.x, listItemOffset, parentTransform.position.z);
    8.             parentTransform.position = tempPos;
    9.  
    10.         }
    11.     }
    12.  
    13.     public void OnPointerDown (PointerEventData eventData) {
    14.         Debug.Log ("OnPointerDown");
    15.         startClick = true;
    16.         mouseStartPos = Input.mousePosition;
    17.         listItemStartPos = parentTransform.position;
    18.     }
    19.  
    20.     public void OnPointerUp (PointerEventData eventData) {
    21.         Debug.Log ("OnPointerUp");
    22.         startClick = false;
    23.         parentTransform.position = listItemStartPos;
    24.     }
     
  2. cruelbob

    cruelbob

    Joined:
    May 26, 2014
    Posts:
    20
    I have similar problem... It's impossible to click button by finger on touch screen if button is child of scrollrect because button moves at this moment and loses focus.
     
    Last edited: Sep 9, 2014
  3. beatelove

    beatelove

    Joined:
    Aug 30, 2014
    Posts:
    18
    it's better than last version:p
     
  4. mh114

    mh114

    Joined:
    Nov 17, 2013
    Posts:
    294
    Customizable drag threshold would solve that one, do vote on the bug if you haven't already. :)
     
  5. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,183
    Hi, I added this today (it won't make b19 :( ).

    Basically when we start a drag you can register an interface for callback to fetch the DragThreshold (default for all dragging is 5 pixels, overridden and customizable in ScrollRect @ 15).
     
    mh114 likes this.
  6. arturmandas

    arturmandas

    Joined:
    Sep 29, 2012
    Posts:
    240
    it seems it is still working this way in 4.6.3..
     
  7. Tehelee

    Tehelee

    Joined:
    Jan 26, 2013
    Posts:
    12
    Hello folks, I'd just like to drop my homebrew solution for this issue.

    When the pointer begins, you climb up the transform parent tree and find the first active scroll rect.
    (If none is found then the solution falls through without interference.)

    You then cache the scroll rect and disable the component.

    When your pointer leaves or finishes you re-enable the scroll rect and dump your reference.

    Simple as pie, I hope you can repurpose the code or concept for your particular scenario.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class ScrollFix : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
    6. {
    7.     ////////////////////////////////
    8.  
    9.     private ScrollRect m_parentScrollRect;
    10.  
    11.     ////////////////////////////////
    12.  
    13.     public void OnPointerDown(PointerEventData eventData)
    14.     {
    15.         Transform query = this.transform;
    16.  
    17.         do
    18.         {
    19.             this.m_parentScrollRect = query.GetComponent<ScrollRect>();
    20.  
    21.             if ((null != this.m_parentScrollRect) && this.m_parentScrollRect && this.m_parentScrollRect.enabled)
    22.             {
    23.                 break;
    24.             }
    25.  
    26.             query = query.parent;
    27.         }
    28.         while ((null != query) && query && (null != query.parent) && query.parent);
    29.  
    30.         if ((null != this.m_parentScrollRect) && this.m_parentScrollRect)
    31.         {
    32.             this.m_parentScrollRect.enabled = false;
    33.         }
    34.  
    35.         return;
    36.     }
    37.  
    38.     ////////////////////////////////
    39.  
    40.     public void OnPointerUp(PointerEventData eventData)
    41.     {
    42.         this.OnPointerExit(eventData);
    43.  
    44.         return;
    45.     }
    46.  
    47.     ////////////////////////////////
    48.  
    49.     public void OnPointerExit(PointerEventData eventData)
    50.     {
    51.         if ((null != this.m_parentScrollRect) && this.m_parentScrollRect)
    52.         {
    53.             this.m_parentScrollRect.enabled = true;
    54.  
    55.             // This is for Touch based input, ScrollRect needs to be notified for elastic movement.
    56.             this.m_parentScrollRect.OnEndDrag(eventData);
    57.      
    58.             this.m_parentScrollRect = null;
    59.         }
    60.  
    61.         return;
    62.     }
    63.  
    64.     ////////////////////////////////
    65.  
    66. }
     
    Last edited: Sep 19, 2015
  8. xaldin-76

    xaldin-76

    Joined:
    Oct 1, 2016
    Posts:
    24
    Thanks for this, and I'm from the future (unity 2019.4.20)..

    I had problem with holding down cards to trigger an event, the cards are in a scroll rect obviously so it's nearly impossible to not trigger a OnPointerUp with a finger, your solution works with me.