Hey guys,
I made a script that detects, single click, double click and drag.
The problem I have is when I double click it also executes a single click.
Any ideas? I spend two days thinking about it
There are examples using Coroutine or tap counter.
Need a little help.
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
startTime = Time.time;
timeSinceLastClick = Time.time - lastClickTime;
if (timeSinceLastClick <= 0.2f)
{
Debug.Log("Double click");
}
lastClickTime = Time.time;
}
if (Input.GetMouseButtonUp(0))
{
if (Time.time - startTime <= touchDelay)
{
Debug.Log("Single click");
}
}
if (Input.GetMouseButton(0))
{
Debug.Log("Drag");
}
}
if (Input.GetMouseButtonUp(0))
{
if (Time.time - startTime <= touchDelay)
{
Debug.Log(“Single click”);
}
}
It's counting how long the click is pressed down, an independent logic from double click. I could be wrong.
I think something like this could work. *(Apologies for writing the comments on the same line. Didn't realize they would look this way here)*
```csharp
[SerializeField] float touchDelay = 0.25f; //The maximumAmount of time between two clicks to consider it a double click
private float doubleClickTime; //the next click have to be within this Time.time+touchdelay to be a double click
private bool clickTriggered = true; //if the double click isn't triggered within this time, trigger the single click
[SerializeField] float dragThreshHold = 0.5f; //After this amount of time, a click is considered a drag
private float dragTime; //how long the current click is held down
private bool wasDragging = false; //To make sure get mouse button up do not trigger a click after drag
void Update()
{
//when the click is finished
if (Input.GetMouseButtonUp(0))
{
//the click finished within the max delay
if (Time.time <= doubleClickTime)
{
Debug.Log("Double click");
clickTriggered = true;
}
else //the click wasn't finished within the double click delay
{
//if the click was dragging, don't trigger clicks
if (wasDragging)
{
wasDragging = false;
}
else // the first click
{
clickTriggered = false;
doubleClickTime = Time.time + touchDelay;
}
}
}
else if (clickTriggered == false && wasDragging == false)
{
//the second click didnt happen within the delay, just trigger the first one
if (Time.time > doubleClickTime)
{
Debug.Log("Single click");
clickTriggered = true;
}
}
//button held down
if (Input.GetMouseButton(0))
{
//held down for long
if (dragTime > dragThreshHold)
{
wasDragging = true;
clickTriggered = true;
Debug.Log("Drag");
}
else
{
dragTime += Time.deltaTime;
}
}
else
{
dragTime = 0; //reset the value if it isn't held down
}
}
Hi @FerdowsurAsif yes, you are correct this is because of this line. So I need some sort of bool. Saying the second click hasn’t happened make a single click.
It seems your script should work, the only problem I see is there is going to be a delay in a single click.
A delay in a single click is not really avoidable when making a system like this. If there was no delay, it would be impossible to distinguish between a single click and merely the first click of the double click, as we cannot tell if a second click is coming in the near future.
The only way you could avoid a delay is if the single-click action was somehow able to be rolled back cleanly when the second click arrives.
One other approach could be always triggering the single click.
Then not triggering the single click on the double click.
So, for double click,
Single click event Always trigger - then - Second click triggers double click event but not single click event again.
Like first click on windows file explorer selects a folder, the double click opens it after selecting.
I think just removing the clickTriggered variable would achieve that from my code. (Need to check)
Maybe if make a counter. It will help? If single click counter ++ , if the time to second click less than 0.5 make counter ++
If click and counter = 1 - we got a single click
If click and counter = 2 - we got double click