- Home /
Android Buttons Responding Poorly To Touch Controls
I'm using the new GUI system in version 5.0.2f of Unity and I've become rather stumped during my testing on my android device; If i tap my buttons and IMMEDIATELY lift my finger off them, they work perfectly as intended. However if i hold my finger on any of the buttons for more than a fraction of a second they rapidly switch between their pressed, highlighted and normal states and seemingly randomly land on one and stick with it. What's causing this and how do i stop it?
I've tried;
Changing the Input Actions per second to 1 rather 10 in the EventSystem
Changing the Drag Threshold to well over values of 100 far from its default setting
Removing all script functionality from the buttons, reducing them to just Sprite Swap buttons
Changing the Button Navigation Settings to None rather than automatic
Here's my setup for the event system, hierarchy and menu design(early design):
I've established it isn't a hardware issue with the SM-T210 tablet, would there be a way for me to write a script that forces the state of the button to remain on clicked for a number of seconds and ignore all other input on that particular button, or another workaround?
If it's worth mentioning it's a 2D game, thankyou in advance for reading or contributing, I've managed to avoid having to ask any questions for the duration of the project but I'm rather stuck for ideas here and can't find anyone else who encountered the problem and resolved it.
Answer by I_CAST_FIST · Jun 17, 2015 at 03:21 AM
Managed to fix it myself after going off and finishing off a dialogue system, FOR ANYONE ELSE EXPERIENCING SIMILAR ISSUES WITH OVERLY RESPONSIVE OR TWITCHY BUTTONS FOR TOUCH SCREENS LIKE ANDROID AND IOS-
I made a new C# script and attached it to an object that i could put as a trigger OnClick for the buttons in question in the inspector with the following-
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class DelayPress : MonoBehaviour
{
public Button thisButton;
public void DoTheThing()
{
StartCoroutine(DelayState());
}
private IEnumerator DelayState()
{
thisButton.interactable = false;
yield return StartCoroutine(UnscaledTimeUtil.WaitForRealSeconds(1));
thisButton.interactable = true;
Debug.Log("coroutine complete");
}
}
Because my menu pauses the game by setting the time scale to 0 i couldn't use "yield return new WaitForSeconds(5);" because the coroutine won't work outside of scaled time. So i found a post here by matthiassoeholm and created an unscaled time utility for the coroutine to work from i called UnscaledTimeUtil, this is his utility code that also works just fine;
public static class CoroutineUtil
{
public static IEnumerator WaitForRealSeconds(float time)
{
float start = Time.realtimeSinceStartup;
while (Time.realtimeSinceStartup < start + time)
{
yield return null;
}
}
}
WHAT THIS DOES - Is it allows you to temporarily disable any extra "presses" or clicks on whatever button you use the function in by an amount of time stored in a float, in my case 1 (1f) second. It functions perfectly for menu navigation because no one will be spamming those buttons for any good reason. Here's what it looks like in the inspector, just make sure to attach your DelayPress Script to a gameobject in your scene so you can drag it onto your new OnClick Function and to add your button in question to the button field in that script on the object-
THAN$$anonymous$$ YOU. I don't know how this issue isn't more common. I've run into it on every Android device I've tried.
Answer by Meltdown · Jun 17, 2015 at 03:28 AM
I've never had issues. But the way I handle button click/touch input is as follows...
Add a field for your script in the Inspector for the button...
[SerializeField] private Button _myButton;
Drag the button to this field on your script to assign it
In your Start() method, wire up your button event handler...
_myButton.onClick.AddListener(OnMyButtonClicked);
In your OnDestroy() method, wire up your remove listener event
_myButton.onClick.RemoveListener(OnMyButtonClicked);
Create a method to handle the button click...
void OnMyButtonClicked() { Debug.Log("My button was pressed!"); }
Unfortunately if the button in question still has a button component in the inspector it still rapidly switches between states even when using a listener, thankyou for the answer though :)
Curiously the legacy gui methods dont cause this issue, but im having trouble reproducing it outside this project :s