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\$ Commented May 29, 2022 at 17:38
  • \$\begingroup\$ you can also add IPointerMoveHandler interface instead of Update method and custom OnPointerMove method \$\endgroup\$ Commented Apr 7, 2023 at 23:57

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.