OnDrag is not invoked with a small dragging movement.

I implemented mobile rotation control with IPointerDownHandler and IDragHandler. It seems fine if the movement is fast enough, but there’s a serious flaw that the OnDrag event never invoked if the dragging amount is very tiny.

Here’s the code.

using UnityEngine;
using UnityEngine.EventSystems;

[RequireComponent(typeof(CanvasGroup))]
public class MobileFPSRotationPanel : MonoBehaviour, MobileFPSUIElement, IPointerDownHandler, IDragHandler, IEndDragHandler {
    ...

    public void OnDrag(PointerEventData eventData) {
        Debug.Log("Drag"); <- It's not invoked if the dragging is too small.
        eventData.Use();
      
        Vector2 currentTouchPosition = eventData.position;
        m_Movement = currentTouchPosition - m_PreviousTouchPosition;
        m_PreviousTouchPosition = currentTouchPosition;
    }

    public void OnEndDrag(PointerEventData eventData) {
        Debug.Log("EndDrag");
        m_Pressing = false;
        m_Movement = Vector2.zero;
    }

    public void OnPointerDown(PointerEventData eventData) {
        Debug.Log("PointerDown");
        if (Interactable == false) {
            return;
        }

        eventData.Use();

        m_Pressing = true;
        m_Movement = Vector2.zero;
        m_PreviousTouchPosition = eventData.position;
    }

    ...
}

I heard reports from a lot of people who have been annoyed by this glitch, which makes it hard to precise aiming. Is this a glitch or an intended feature? If it’s intended, then how to detect every drag movement even if it’s super tiny?

Using Unity 2019.4.3f1.

I bet you’re talking about Android!!

If you are, it’s a horribly irritating feature in many versions of Android that require a certain minimum finger travel before registering ANY travel.

Your code is nice but I bet you your code is not even being TOLD that the finger moved, thanks to Android.

Put some Debug.Log() logging in and see for yourself.

The only way around it that I know is to access the raw Android native touches and do ALL the input processing yourself.

WARNING: Touch.rawInput is NOT the same thing as the raw Android system touch! That’s simply where your finger first went down.

Good luck.

I figured it out, maybe it’s the intended feature of Unity. There’s a drag threshold in Event Systems which cause this behavior.

The Drag Threshold property represents the number of pixels a UI object can be moved before it is considered being “dragged”. People don’t have perfectly steady hands, so when they are trying to click or tap a UI item their mouse or finger may move slightly. This Drag Threshold allows the player to move their input slightly (or a lot if you make this number high) before the item they are selecting is being “dragged” rather than “clicked”.

I rather change this value, I updated the code to calculate movement in Update method and now it works fine.