I want to detect double click on UI Image but i found loads of way to do it, some of them don’t work (onDoubleClick() for instance) but i don’t know why.
And i attach this componement to my UI Image. This script return “DoubleClick” when i doubleClick. But the problem is that the following part is not triggered: (even if my mouse is above the UI Image…)
if (this.GetComponent<RectTransform>().rect.Contains(Input.mousePosition)) {
Do you have any ideas (or a best way) to do this ?
Your basic concept for a double-click is in the right direction. However, when using the UI, you should use the UI functions, not the standard Input classes.
In this case, I’d make your script an EventTrigger component. Add a method for OnPointerDown that applies basically the same logic as your DoubleClick function uses. It’s a mindset shift to switch from bool-based logic to event-driven logic, but you’ll find yourself much better off ultimately.
If you need help beyond the code samples on that page, ask away.
When I have used this solution in the past, it doesn’t work, because if you are trying to interpret single clicks and double clicks on the same component, then you get two events fired: one with eventData.clickCount == 1, and one with eventData.clickCount == 2. This has always prevented this answer from working for me, because inevitably when I want to detect double clicks, it’s because there is already a single click handler I’m using on that component. It took me hours of fiddling with this the first time to discover that’s why my logic didn’t work right.
Thank you guys, Randy-Edmonds solution worked for me partially, it detected double clicks using mouse but only detected a single click with touch Input (I was using an iPad with Unity Remote). However, the code provided by Mayo54 in this comment:
Worked for me for both mouse click and touch input, I used OnPointerClick instead of OnPointerDown but it should work anyway.
using UnityEngine;
using UnityEngine.EventSystems;
public class MultipleClick : MonoBehaviour, IPointerClickHandler
{
//[SerializeField] private int numberOfClicks = 2;
float clicked = 0;
float clicktime = 0;
float clickdelay = 0.5f;
public void OnPointerClick(PointerEventData eventData)
{
/*
if (eventData.clickCount == numberOfClicks)
{
Debug.Log("double click");
}
*/
// Detecting double click
clicked++;
if (clicked == 1)
clicktime = Time.time;
if (clicked > 1 && Time.time - clicktime < clickdelay)
{
// Double click detected
clicked = 0;
clicktime = 0;
Debug.Log("Double Click: " + this.GetComponent<RectTransform>().name);
}
else if (clicked > 2 || Time.time - clicktime > 1)
clicked = 0;
}
}
The above examples work if a user performs a “clean” double click as expected. I believe the logic could fail however if the user does something more unexpected such as a single click followed by a double click.
This expression needs more work. I don’t believe it will respond correctly to every usecase:
The following example is possibly easier to understand and code and as such doesn’t suffer from logical errors. If you don’t need the single click just don’t add any code to the method.
using UnityEngine;
using System.Timers;
public class DoubleClick : MonoBehaviour
{
private readonly Timer _MouseSingleClickTimer = new Timer();
// Start is called before the first frame update.
void Start()
{
_MouseSingleClickTimer.Interval = 400;
_MouseSingleClickTimer.Elapsed += SingleClick;
}
void SingleClick(object o, System.EventArgs e)
{
_MouseSingleClickTimer.Stop();
System.Diagnostics.Debug.WriteLine("Single Click");
//Do your stuff for single click here....
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (_MouseSingleClickTimer.Enabled == false)
{
// ... timer start
_MouseSingleClickTimer.Start();
// ... wait for double click...
return;
}
else
{
//Doubleclick performed - Cancel single click
_MouseSingleClickTimer.Stop();
//Do your stuff here for double click...
System.Diagnostics.Debug.WriteLine("Double Click");
}
}
}
}
Previous implementation to Randy-Edmonds is nice, since if you dont have/know of the clickCount property, its a clean implementation. However, I just implemented it, the Randy-Edmonds solution and it’s the way to go. If your logic it’s not working, the problem it’s in your logic, or the analysis of the results. These both solutions should be implemented inside OnPointerClick. OnPointerDown will wait a bit to raise the event, since its for detecting MouseDown like events. So if you expect a “clean” double click using OnPointerDown, sit down, light your best cigar, and get yourself comfy on the bench because that train is not coming. Please let’s try to properly analize user cases to create great UI logic, instead of justify our own mistakes.
Hey guys,
what would be the approach if just want to detect a double-click of the middle mouse button anywhere in the scene?
To trigger reset the camera rotation.
I’ve also encountered the issue when you click first, then trying double click doesn’t work right. So I wanted to share how I fixed it for my use case by still using a variation of Mayo54’s original approach: