- Home /
Strange Input.GetMouseButtonDown behaviour
I'm trying to create a simple script that sets a starting point at the location of the mouse once I click down, and continually updates the ending point to meet the mouse's current position until I let go of the mouse. Having read this it seems Input.GetMouseButtonDown is only true for a single frame when the mouse button is initially pressed and so it waslogical to me that I can set the starting point when Input.GetMouseButtonDown(0) is true, and have the ending point change every Update() until Input.GetMusebuttonUp(0) becomes true.
The problem is, that Input.GetMouseButtonDown actually seems to be true for multiple frames while I have my mouse button held down. Below is a code snippet from my tests of this, which shows that Input.GetMouseButtonDown(0) returns true repeatedly, as it prints the message "holding" a hundred or so times per second. It is also worth noting that Input.GetMouseButtonUp(0) returns true precisely once during a click, which is what I expected GetMouseButtonDown to do as well.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MouseTracker : MonoBehaviour {
// Resolution dependent and independent mouse tracking variables
private Vector2 rawPosition;
private Vector2 normalisedPosition;
private LineRenderer sketchLine;
private Vector2 lineOrigin;
private Vector2 lineEnd;
private Vector2 lineVector;
public Image lineImage;
private bool mouseHeld;
void Start () {
Debug.Log("test: " + (500.0f / 1366.0f));
sketchLine = GetComponent<LineRenderer>();
sketchLine.enabled = false;
}
void Update () {
DrawLine();
}
void DrawLine()
{
if (Input.GetMouseButtonDown(0))
{
mouseHeld = true;
lineOrigin = rawPosition;
}
else if (Input.GetMouseButtonUp(0))
{
mouseHeld = false;
Debug.Log("letting go");
return;
}
if (!mouseHeld)
{
return;
}
Debug.Log("hello");
lineEnd = rawPosition;
lineVector = lineEnd - lineOrigin;
lineImage.rectTransform.sizeDelta = new Vector2(lineVector.magnitude, 15);
lineImage.rectTransform.pivot = lineOrigin;
lineImage.rectTransform.position = lineOrigin;
float angle = Mathf.Atan2(lineVector.y, lineVector.x) * Mathf.Rad2Deg;
lineImage.rectTransform.rotation = Quaternion.Euler(0, 0, angle);
}
}
What I basically need to know is why this is happening. Am I misunderstanding what Input.GetMousebuttonDown actually does or is there another problem? Also, if I am misunderstanding the function of GetMouseButtonDown, what should I be using instead?
Thanks in advance for your help.
Edit 1: Further checking has shown me that Input.GetMouseButtonDown(0) does not return true for every single frame. I held it down for 10 seconds while the game ran at a few hundred frames per second but it returned true 316 times. This is roughly true for the script suggested by MaxGuernseyIII.
Edit 2: Added the entirety of the script I was testing.
Also, I can confirm that this is not due to multiple objects using this script, even if I only have one object in the scene, this issue still occurs.
Can't reproduce this with the code you provided. Is it possible to update your question with the full $$anonymous$$onoBehaviour? Alternatively, you can compare the behavior of the code I put in my answer to the behavior of your $$anonymous$$onoBehaviour.
You'll be happy to know that this code does reproduce the problem. Give me a bit and I'll see if I can help track it down.
Scratch that. I was fooled by the extra log of Hello.
Okay, I tried the following code. There's a slight modification of one extra log-write.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class $$anonymous$$ouseTracker : $$anonymous$$onoBehaviour
{
// Resolution dependent and independent mouse tracking variables
private Vector2 rawPosition;
private Vector2 normalisedPosition;
private LineRenderer sketchLine;
private Vector2 lineOrigin;
private Vector2 lineEnd;
private Vector2 lineVector;
public Image lineImage;
private bool mouseHeld;
void Start()
{
Debug.Log("test: " + (500.0f / 1366.0f));
sketchLine = GetComponent<LineRenderer>();
sketchLine.enabled = false;
}
void Update()
{
DrawLine();
}
void DrawLine()
{
if (Input.Get$$anonymous$$ouseButtonDown(0))
{
mouseHeld = true;
lineOrigin = rawPosition;
Debug.Log("pressing");
}
else if (Input.Get$$anonymous$$ouseButtonUp(0))
{
mouseHeld = false;
Debug.Log("letting go");
return;
}
if (!mouseHeld)
{
return;
}
Debug.Log("hello");
lineEnd = rawPosition;
lineVector = lineEnd - lineOrigin;
lineImage.rectTransform.sizeDelta = new Vector2(lineVector.magnitude, 15);
lineImage.rectTransform.pivot = lineOrigin;
lineImage.rectTransform.position = lineOrigin;
float angle = $$anonymous$$athf.Atan2(lineVector.y, lineVector.x) * $$anonymous$$athf.Rad2Deg;
lineImage.rectTransform.rotation = Quaternion.Euler(0, 0, angle);
}
}
That code, with the mouse held-down for several seconds, generated these log entries:
pressing (1)
hello (324)
letting go (1)
For whatever reason, I cannot upload a 40k .png, so you'll have to take my word for it.
If the same script (the one I modified) produces substantively different results for you then we have to look at hardware and configuration. Do you have an input
I think you already know this but, the "why" part of the problem notwithstanding, you can just change your first if statement to:
if (!mouseHeld && Input.Get$$anonymous$$ouseButtonDown(0))
Also - and for some reason this is the thing, today - there's a state pattern in your problem.
Even with the new example you provided, getmousebuttondown still returns true multiple times with a single click. I'm not sure it's hardware related as I'd imagine that would make getmousebuttonup return true as well. I've also tried with multiple mice though admittedly not with multiple computers (only having access to one).
I have also tried another game development tool with a similar function to getmousebuttondown and it seems to behave exactly as it should there, but not here which makes me think that there's some $$anonymous$$or issue with the way that Unity is configured/running on my computer.
So, when you run the version of the script I posted and hold the mouse button, you get the same number of "pressing" log entries as "Hello" entries?
And you're doing an exact copy paste of the script, not coping in equivalent edits?
If so, I agree we need to start pursuing configuration. The first thing we can do is eli$$anonymous$$ate the configuration of your unity project. We could create a new project on your machine, paste the version of the script I posted into it, and test it.
On a new project, the issue appears is now impossible to replicate. Though funnily enough, it still seems to exist on certain older projects. So it seems you were right about project configuration issues. Thanks for putting so much effort helping me with this, I really appreciate it.
One last thing, I don't believe that I can accept a comment as the correct answer. Is there away to do this with your comment? Or is there a procedure for dealing with this to help others in future? If not, maybe it's best for you to edit your answer to include that as a possibility and then I can accept that answer.
Again, thank you so much.
I'll just change my answer to include this information.
Answer by MaxGuernseyIII · Sep 26, 2017 at 12:22 AM
After a lot of attempted diagnosis, we ruled out your code. Here is a simplified version of it that others can use to test their environment.
using UnityEngine;
public class TestMouseButtons : MonoBehaviour
{
private bool mouseHeld;
private Vector3 lineOrigin;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
mouseHeld = true;
lineOrigin = Input.mousePosition;
Debug.Log("holding");
}
else if (Input.GetMouseButtonUp(0))
{
mouseHeld = false;
Debug.Log("letting go");
return;
}
}
}
The three things left to check were as follows:
Project configuration
Unity install
Hardware
To test the project configuration (what it ended up being in your case), create a brand new project, paste that script in, and see if it still reproduces the problem. If a new unity project doesn't reproduce the problem, then you know it's your project configuration.
Unity install and hardware are both more laborious tot test - you have to replace the possibly broken hardware or corrupt install. That's why we start with the project.
$$anonymous$$y code was part of a void function which was called only during update. I have since tried replacing the entirety of that script with the example you provided, but it behaves more or less the same as $$anonymous$$e did.
So, to be clear, if you hold down on the mouse button, it will just keep adding "holding" lines to the log?
If that's true, why not paste the exact, entire $$anonymous$$onoBehaviour into an edit of your question or a comment on it. That way, people could try to reproduce this on their machines. $$anonymous$$aybe you found a subtle bug?
Your answer
Follow this Question
Related Questions
Help In Making a SphereCast for 3D Tire! Working RayCast Script included! 0 Answers
Detect mouse clicks anywhere on the screen except given gameobject 2 Answers
Unity sometimes misses Mouse Button Release 1 Answer
Differentiate left, right and both mouse inputs 0 Answers
Touch and MouseClick - One Game for Mobile and Desktop 3 Answers