1
\$\begingroup\$

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 reported a lot of people have been annoyed by this glitch, which makes it hard to precise aiming. Is this a glitch or an intended feature of Unity? If it's intended, then how should I detect every drag movement even if it's super tiny?

Using Unity 2019.4.3f1.

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

You can simply set the drag threshold of the event system:

enter image description here

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".

Or you can simulate the drag yourself by update():

using UnityEngine;
using UnityEngine.EventSystems;

[RequireComponent(typeof(CanvasGroup))]
public class MobileFPSRotationPanel : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    private bool isDragging;
    void Update()
    {
        if (!isDragging)
        {
            return;
        }
        OnPointerMove(Input.mousePosition);
    }
    public void OnPointerMove(Vector3 position)
    {
        Debug.Log(position);
    }
    public void OnPointerDown(PointerEventData eventData)
    {
        isDragging = true;
    }
    public void OnPointerUp(PointerEventData eventData)
    {
        isDragging = false;
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ It works perfectly. Thank you! \$\endgroup\$
    – modernator
    Commented May 29, 2022 at 17:38
  • \$\begingroup\$ you can also add IPointerMoveHandler interface instead of Update method and custom OnPointerMove method \$\endgroup\$
    – MarsPeople
    Commented Apr 7, 2023 at 23:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .