- Home /
UI Button OnClick Sensitivity for High DPI Devices
I've got a Unity project running on a Samsung Galaxy S5, and users are having issues pressing buttons.
They need to repeatedly click on any button using the OnClick handler. I believe this is because of very small movements in their finger when they touch the device reading as scrolling rather than a simple touch. Adding an OnPointerDown event trigger of course avoids the issue...
Unfortunately, some of my buttons are on items that take up large chunks of a ScrollRect. This means that I can't easily switch to using EventTriggers to simply capture OnPointerDown - that would unnecessarily trigger the button when the person is actually scroll-dragging.
Is there any way I can change the 'scroll' sensitivity within the Button generally? I'd like to adjust it to suit Screen.dpi, since most devices with a higher resolution screen have an accompanying increase in touch resolution.
Answer by FireOApache · Mar 06, 2016 at 11:35 AM
Looking at Unity's UI implementation (on tag 5.3) I've found that (1) is called by (2) which uses pixelDragThreshold attribute defined by the current EventSystem instance in the scene...
A possible (and maybe the simplest) solution would be to use a script which will change that threshould based on the screen PPI (Screen.dpi) of each device.
1. private static bool ShouldStartDrag(...) @ PointerInputModule.cs : 228
2. protected virtual void ProcessDrag(...) @ PointerInputModule.cs : 248
The following script does the drag threshold adaptation, put this in your event system game object:
using UnityEngine;
using UnityEngine.EventSystems;
public class DragCorrector : MonoBehaviour
{
public int baseTH = 6;
public int basePPI = 210;
public int dragTH = 0;
void Start()
{
dragTH = baseTH * (int)Screen.dpi / basePPI;
EventSystem es = GetComponent<EventSystem>();
if (es) es.pixelDragThreshold = dragTH;
}
}
Here's a very simple script to check the device's PPI... you can run this on different phones to see if Unity is calculating it right:
using UnityEngine;
using UnityEngine.UI;
public class PPIViewer : MonoBehaviour
{
public Text label;
void Start()
{
if (label != null)
{
label.text = "PPI: " + Screen.dpi.ToString();
}
}
}
Answer by Roixo · Jan 12, 2018 at 06:33 PM
This code is more efficient for me: link text
public class DragThresholdUtil : MonoBehaviour {
void Start () {
int defaultValue = EventSystem.current.pixelDragThreshold;
EventSystem.current.pixelDragThreshold =
Mathf.Max(
defaultValue ,
(int) (defaultValue * Screen.dpi / 160f));
}
}
Answer by SimonDarksideJ · Jun 03, 2016 at 12:14 PM
Nice little fix. Would you be OK with me adding this to the UI extensions project? Should prove valuable.
Sure, please go ahead! Could you credit me on that somehow?
Definitely, everyone gets credited for everything on the project :D https://bitbucket.org/ddreaper/unity-ui-extensions
And thanks!
Just in time for the upco$$anonymous$$g release (which won't happen if I don't stop adding things :D)
Answer by BeshevGames · Feb 26, 2017 at 08:56 AM
Try to increase the Drag Treshold in the Event System to about 16 :) .
Answer by josefvesely · Mar 04, 2018 at 11:32 AM
I came up to following blog post when I was solving this issue:
It introduces script that update Drag Threshold according to DPI.