Search Unity

OnBeginDrag with delay

Discussion in 'Immediate Mode GUI (IMGUI)' started by PrizPro, Jan 24, 2018.

  1. PrizPro

    PrizPro

    Joined:
    Feb 7, 2017
    Posts:
    7
    Hi!
    I want to execute OnBeginDrag with a delay.

    Objects are in ScrollRect.

    To work Scroll Rest. I want the object to move after 1 second.
    While the mouse is on it

    The component is activated. But the OnBeginDrag event does not occur.
    You need to click on the new one. What is not permissible.

    P.S. Excuse me. My English is poor

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5. using UnityEngine.UI;
    6.  
    7. public class dragh : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
    8.  
    9.     public static GameObject itemBeingDragged;
    10.     Vector3 startPosition;
    11.     Transform startParent;
    12.  
    13.     public void OnBeginDrag(PointerEventData eventData)
    14.     {
    15.         itemBeingDragged = gameObject;
    16.         startPosition = transform.position;
    17.         startParent = transform.parent;
    18.         Debug.Log("");
    19.     }
    20.  
    21.     public void OnDrag(PointerEventData eventData)
    22.     {
    23.         transform.position = eventData.position;
    24.     }
    25.  
    26.     public void OnEndDrag(PointerEventData eventData)
    27.     {
    28.         itemBeingDragged = null;
    29.         transform.position = startPosition;
    30.     }
    31. }
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5. using UnityEngine.UI;
    6.  
    7. public class ControlDrop : MonoBehaviour, IPointerDownHandler {
    8.  
    9.     private float controlTime = 1f;
    10.     private float currentTime = 0f;
    11.  
    12.     private bool active = false;
    13.  
    14.     PointerEventData e;
    15.    
    16.     public void OnPointerDown(PointerEventData eventData)
    17.     {
    18.         active = true;
    19.         GetComponent<dragh>().enabled  = false;
    20.         e = eventData;
    21.  
    22.     }
    23.  
    24.     void Update () {
    25.         if (Input.GetMouseButton (0) && active==true) {
    26.             currentTime +=Time.deltaTime;
    27.             if (currentTime >= controlTime)
    28.             {
    29.                 active = false;
    30.                 GetComponent<dragh>().enabled = true;
    31.                 Debug.Log("ADD");
    32.             }
    33.            
    34.         }
    35.  
    36.         if (Input.GetMouseButtonUp (0)) {
    37.             currentTime = 0f;
    38.             active = false;
    39.             GetComponent<dragh>().enabled  = false;
    40.         }
    41.     }
    42. }
     
  2. PrizPro

    PrizPro

    Joined:
    Feb 7, 2017
    Posts:
    7
  3. PrizPro

    PrizPro

    Joined:
    Feb 7, 2017
    Posts:
    7
    Here's what I want to get:
     
  4. logicandchaos

    logicandchaos

    Joined:
    May 16, 2016
    Posts:
    10
    I'm looking for the same thing, I'll post if I find a solution. I got the same problem draggable object in a scroll view.
     
  5. logicandchaos

    logicandchaos

    Joined:
    May 16, 2016
    Posts:
    10
    Hey I'm working on a solution, not finished it yet, but I add IPointerDownHandler, IPointerUpHandler to the objects class, then implement them like this:
    float mouseDownTime = 0;
    float dragDelay = .4f;
    bool mouseDown;

    public void OnPointerDown(PointerEventData eventData)
    {
    mouseDownTime = 0;
    mouseDown = true;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
    mouseDown = false;
    mouseDownTime = 0;
    }

    public void Update()
    {
    if (mouseDown)
    {
    mouseDownTime += Time.deltaTime;
    if (mouseDownTime > dragDelay)
    {
    transform.GetChild(1).gameObject.SetActive(true);
    }
    }
    else
    {
    transform.GetChild(1).gameObject.SetActive(false);
    }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
    if (!transform.GetChild(1).gameObject.activeSelf)
    {
    eventData.pointerDrag = null;
    return;
    }
    }

    transform.GetChild(1) is a highlighting image, it activates when you have held the mouse down for long enough and deactivates when the mouse is released, the begin drag checks to see if the image is activated before dragging, this part:

    eventData.pointerDrag = null;
    return;
    needs to be changed because the scrollview is still not clickable through the draggable gameObject, I think the solution is to disable BlockRaycast in CanvasGroup component, but I haven't tried yet, see this post as well, hope this helps: https://stackoverflow.com/questions/28202442/how-to-stop-drag-event-in-onbegindrag-in-unity-4-6

    Sorry can't remember how to enclose code on here.
     
  6. logicandchaos

    logicandchaos

    Joined:
    May 16, 2016
    Posts:
    10
    I changed eventData.pointerDrag = null; to eventData.pointerDrag = transform.parent.parent.parent.gameObject; that triggers the scrollview drag, but it's a bit buggy, it doesn't work until the content has been dragged once, and it moves the content at the start of the drag..
     
  7. better_walk_away

    better_walk_away

    Joined:
    Jul 12, 2016
    Posts:
    115
    I encountered similar problem. There were many child objects in my ScrollRect that had the IBeginDragHandler, IDragHandler, IEndDragHandler implemented, so in my case, the children in my ScrollRect were also draggable.
    I determined whether a child can be dragged by evaluating the angle of user's dragging, if the angle exceeds certain value, then the user will drag the ScrollRect instead.
    I am not using Unity's ScrollRect, I write my own custom ScrollRect, it very simple, just implement IBeginDragHandler, IDragHandler, IEndDragHandler and we are done.
    When the OnBeginDrag of one of the children is triggered, it checks the angle of the user's dragging using pointerData.delta, if it exceeds a certain angle, we feed the pointerData to our custom ScrollRect using scrollRect.OnBeginDrag(pointerData). And When OnDrag is triggered, we then feed the pointerData to our custom ScrollRect using scrollRect.OnDrag(pointerData). This way, user will be able to drag the ScrollRect instead.
     
    logicandchaos likes this.