Double click mouse detection ?

Hello world !

I want to make a double-click function with js. But when I tried to make it, I got messed with Time.time :D. So can anyone help with that ?

Thanks in advance !

double click really means 2 clicks within a narrow range of time

bool one_click = false;
bool timer_running;
float timer_for_double_click;

//this is how long in seconds to allow for a double click
float delay;
if(input.GetMouseButtonDown(0))
{
   if(!one_click) // first click no previous clicks
   {
     one_click = true;
     
     timer_for_double_click = time.time; // save the current time
     // do one click things;
   } 
   else
   {
     one_click = false; // found a double click, now reset
     
     do double click things
   }
}
if(one_click)
{
   // if the time now is delay seconds more than when the first click started. 
   if((time. time - time_for_double_click) > delay
{

//basically if thats true its been too long and we want to reset so the next click is simply a single click and not a double click.

    one_click = false;
   
}

hope that helps!
dont forget to mark if answered.

If you stay with the EventSystem method, you don’t need to check timings and do it manually, the event data generated by each pointer press will do it for you.

Step 1: Learn about the EventSystem and EventTriggers scripts:

UI Events and Event Triggers - Unity Official Tutorials - YouTube (Lovely YouTube video)

Step 2: For non-UI elements, you can add a EventTrigger to them too, but you also need to add a Physics Raycaster to the camera you’re using. Then the stuff outlined in the tutorial above will work for 3D objects (and 2D objects if a 2D game and the 2D Raycaster is used)

Step 3: Get involved with Pointer event data

If you use this system, and you set up a callback in the editor for a pointer click on GameObject, then you can’t control things like which mouse button was pressed or (as per the original question) whether it’s a single or double click. Your click function will get called whichever button is used, however many time you click.

However, the EventSystem and Input Modules collect all of that stuff by default for you, you just need to get at it. To access it, you just need to do some extra stuff:

http://answers.unity3d.com/answers/1229912/view.html

Hope that helps.

this is tested and working,good luck:


private var lastClickTime:float=0;

var catchTime:float=.25;

function Update () {

if(Input.GetButtonDown("Fire1")){
	if(Time.time-lastClickTime<catchTime){
		//double click
		print("done:"+(Time.time-lastClickTime).ToString());
	}else{
		//normal click
		print("miss:"+(Time.time-lastClickTime).ToString());
	}
	lastClickTime=Time.time;
}

}

try to use Event.current.clickCount

such like

void OnGUI()
{
    if(Event.current.isMouse && Event.current.button == 0 && Event.current.clickCount > 1)
    {
        Debug.Log(Event.current.clickCount);
    }
}

Corutines can be very useful for this purpose:

        private WaitForSeconds doubleClickTreashHold = new WaitForSeconds(1f);
        private int clickCount;

        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                OnPointerClick();
            }
        }

        private void OnPointerClick()
        {
            clickCount++;
            if (clickCount == 2)
            {
                print("double click!");
                clickCount = 0;
            }
            else
            {
                StartCoroutine(TickDown());
            }
        }

        private IEnumerator TickDown()
        {
            yield return doubleClickTreashHold;
            if (clickCount > 0)
            {
                clickCount--;
            }
        }

Almost…

Here is something that does single, double and long.

if(Input.GetMouseButtonDown(0))
{
	_buttonDownPhaseStart = Time.time;	
}
		
if (_doubleClickPhaseStart > -1 && (Time.time - _doubleClickPhaseStart) > 0.2f)
{
        Debug.Log ("single click");
        _doubleClickPhaseStart = -1;
}
		
if( Input.GetMouseButtonUp(0) )		
{
         if(Time.time - _buttonDownPhaseStart > 1.0f)
	{
		Debug.Log ("long click");
		_doubleClickPhaseStart = -1;
	}
	else
	{
		if (Time.time - _doubleClickPhaseStart < 0.2f)
		 {
		      Debug.Log ("double click");
		      _doubleClickPhaseStart = -1;
		 }
		 else
		 {
		    _doubleClickPhaseStart = Time.time;
		 }	
	}
}

bool mouseClicksStarted = false;
int mouseClicks = 0;
float mouseTimerLimit = .25f;

public void OnClick(){
	mouseClicks++;
	if(mouseClicksStarted){
		return;
	}
	mouseClicksStarted = true;
	Invoke("checkMouseDoubleClick",mouseTimerLimit);
}

 
private void checkMouseDoubleClick()
{
	if(mouseClicks > 1){
		Debug.Log("Double Clickedd");
		
	}else{
		Debug.Log("Single Clicked");
		
	}
	mouseClicksStarted = false;
	mouseClicks = 0;
}

Because I’m trying to stay in a good mood today.
And also, more people should post in JAVA!

This script allows you to set both a click, and double right click, while differentiating if the left was clicked first or the right. This recognition allows the user to set 10 or more key combinations with just the mouse alone!

It doesn’t work perfect, for example, when holding left mouse, you cannot d-click the right mouse function. But, if you hold the mouse button, and slide transfer into a right button, it will detect and lock the right button when left mouse is released!

Please expand upon this, as I most certainly am. This community has given me a lot towards my project in code, and understanding, so I submit this to give a little back. Thank you all.

Enjoy

var checkKeyDown:			float=0.0;
var checkKeyWasDown:		boolean=false;	
var checkClick:boolean=false;		
var leftClickLock:boolean=false;
var rightClickLock:boolean=false;			
var dClickR:boolean=false;

    				
function input()
 {if(Input.GetMouseButton(0))			
					{	//checkKeyDown=1.0;checkKeyWasDown=true;
						if(!Input.GetMouseButton(0)){}
						else {	leftClickDown=true;
								if(!rightClickLock) 
								{	leftClickLock=true;
									if (Input.GetMouseButton(1))	{callFunction();}	
									else 							{attack();}}
								else //rClick locked 
								{	if (Input.GetMouseButton(1))	{callFunction();
																	walk(10.0);}
						else {rightClickLock=false;}	}}}
																								
					else if (Input.GetMouseButton(1))	
					{	checkKeyDown=1.0;checkKeyWasDown=true;
						if(!leftClickLock)	
						{	rightClickLock=true;
							if (!Input.GetMouseButton(0))
							{	
								if(checkClick){dClickR=true; callFunction();}
							else {callFunction();}}}
						else
						{	leftClickLock=false;	}}
																
					else
					{	leftClickDown=false;
						rightClickLock=false;
						leftClickLock=false;
						if(checkKeyDown>0.0) {checkKeyDown-=10.5* Time.deltaTime; checkClick=true;}
						else {checkKeyWasDown=false;checkClick=false; dClickR=false;} }

For such a things I’m using coroutine like this:

private float LastTimeClick = 0;
private bool DoubleClicked = false;
private readonly float DoubleClickDelay = 0.2f;

private void MouseClicked(){
	if(Time.time - LastTimeClick > DoubleClickDelay){
		DoubleClicked = false; StartCoroutine(someIE (DoubleClickDelay));
	}
	else{DoubleClick = true;}
	LastTimeClick = Time.time;
}

private IEnumerator someIE (float waitTime){
	yield return new WaitForSeconds (waitTime);
	if(DoubleClicked){// do this}
	else{// do this}
}

Here’s a another way to do it using existing Unity OnClick events.

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class DoubleClickFunctionality : MonoBehaviour {

    public float timeBetweenClicks = 1f;
    bool beingClicked = false;
    Button thisButton;

    void Start () {

        thisButton = GetComponent<Button>();
        thisButton.onClick.AddListener(CheckDoubleClick);
    }
	
    void CheckDoubleClick()
    {
        if (!beingClicked)
        {
            StartCoroutine(ClickTimer());
        }
        else
        {
            StopCoroutine(ClickTimer());
            beingClicked = false;
            // Double click functionality here
        }
    }

    IEnumerator ClickTimer()
    {
        beingClicked = true;
        yield return new WaitForSeconds(timeBetweenClicks);
        beingClicked = false;
    }
}

private float tapTime = 0;
private float tapThreshold = 0.25f;
private int tapCounter = 0;

public void checkForDoubleCLick()
        {
           
            if (Input.GetMouseButtonDown(0))
            {
                tapCounter ++;
                tapTime = Time.time;
                if (tapCounter > 1 && Time.time < tapTime + tapThreshold)
                {
                    Debug.Log("Double click!!"); //do function here
                    tapCounter = 0;
                    tapTime = 0;
                }
            }
            if (Time.time > tapTime + tapThreshold)
            {
                tapCounter = 0;
                tapTime = 0;
            }
        }

Maybe there’s better ways but calling this function inside Update() works for me

Super simple, using IPointerClickHandler:

using UnityEngine.EventSystems;

public class DoubleClicker: MonoBehaviour, IPointerClickHandler
{
	public void OnPointerClick(PointerEventData eventData)
	{
		if (eventData.clickCount == 2 && eventData.button == PointerEventData.InputButton.Left) {
			// something-something double-left-click
		}
	}
}

public class DoubleClick : MonoBehaviour {
bool one_click;
public float delay;
float timeCounter;
private void Start()
{
timeCounter = delay;
}
private void Update()
{

    if (Input.GetMouseButtonUp(0))
    {
        if (!one_click)
        {
            Debug.Log("one");
            one_click = true;
        }
        else
        {
            Debug.Log("two");
            one_click = false;
        }
    }

    if (one_click)
    {
        timeCounter -= Time.deltaTime;
        if (timeCounter <= 0)
        {
            one_click = false;
            timeCounter = delay;
        }
    }

}

}

I know I’m 8 years late to the party but here’s a pretty straightforward solution:

    public float firstClickTime;
    public float secondClickTime;
    public int numberOfTimesClicked = 0;

    private bool DoubleClickDetected(int mouseButton, float threshold)
    {
        if(Input.GetMouseButtonDown(mouseButton))
        {
            numberOfTimesClicked++;

            switch(numberOfTimesClicked)
            {
                case (1):
                firstClickTime = Time.time;
                break;

                case (2):
                secondClickTime = Time.time;
                numberOfTimesClicked = 0;
                if((secondClickTime - firstClickTime) < threshold) return true;                
                break;
            }
        }
        return false;
    }

I’ve passed a bit of time trying to have a clean solution and easy to use. I hope this might help you guys.

1) Create a new classe called DoubleClickListener in the file Scripts/DoubleClickListener.cs with the following content:

using UnityEngine;
using System.Collections;
class DoubleClickListener  {
  bool firstClick = false;
  float runningTimerSecond;

  float delay = 0.25F;

  public DoubleClickListener() { }

  public DoubleClickListener(float delay) {
    this.delay = delay;
  }

  public bool isDoubleClicked() {
    // If the time is too long we reset first click variable
    if (firstClick && (Time.time - runningTimerSecond) > delay) {
      firstClick = false;
    }

    if (!firstClick) {
      firstClick = true;
      runningTimerSecond = Time.time;
    } else {
      firstClick = false;
      return true;
    } 
    
    return false;
  }
}

2) Where you want initialize it. For eg:

public class Stalk : MonoBehaviour {
  ...
  private DoubleClickListener dbl = new DoubleClickListener(); // (optionnal: pass a float as the delay)
  ...

3) In the Unity method void OnMouseDown() call dbl.isDoubleClicked() in an if statement:

// On click, add a leaf.
void OnMouseDown() {
    
  if (dbl.isDoubleClicked()) {
    LOGGER.Warning("DOUBLE CLICKED");
  }
}

As you can see, only dbl.isDoubleClicked() is necessary and will tell you if it was double click with your specified interval. Also, this code can be reused for multiple scripts.

Cheers,
Yves Lange