Reputation: 19881
I have a source MonoBehavior
script with these methods:
private void Update () {
if (Input.GetMouseButton(0)) {
HandleInput();
}
}
private void HandleInput () {
Ray inputRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(inputRay, out hit)) {
var position = transform.InverseTransformPoint(hit.point);
Coordinates coords = Coordinates.FromPosition(position);
HexCell cell = null;
if (!cells.TryGetValue(coords, out cell)) {
var err = string.Format("{0} is an invalid position and coordinates are improperly calculated: {1}", position, coords);
print(err);
throw new System.ArgumentException(err);
}
print(string.Format("[{0}] cell: [{1}] {2}", DateTime.Now, cell.id, cell.coordinates));
OnCellTouched(cell);
}
}
The mesh is transparent and I get the hexagon (cell) as expected. In the editor, I get a single message output when I click on a cell:
[05.31.2017.14.15.14.2836] cell: [0] [x=0;y=0;z=0]
[05.31.2017.14.15.15.7359] cell: [197] [x=12;y=-22;z=10]
However, when I build and run the application: single-click on any cell, the following is logged 4 - 6 times per click:
[05.31.2017.14.57.50.1588] cell: [0] [x=0;y=0;z=0]
[05.31.2017.14.57.50.1695] cell: [0] [x=0;y=0;z=0]
[05.31.2017.14.57.50.1861] cell: [0] [x=0;y=0;z=0]
[05.31.2017.14.57.50.2028] cell: [0] [x=0;y=0;z=0]
[05.31.2017.14.57.50.2195] cell: [0] [x=0;y=0;z=0]
[05.31.2017.14.57.52.6195] cell: [197] [x=12;y=-22;z=10]
[05.31.2017.14.57.52.6360] cell: [197] [x=12;y=-22;z=10]
[05.31.2017.14.57.52.6530] cell: [197] [x=12;y=-22;z=10]
[05.31.2017.14.57.52.6691] cell: [197] [x=12;y=-22;z=10]
[05.31.2017.14.57.52.6857] cell: [197] [x=12;y=-22;z=10]
Is it possible that a single click is propagated multiple times by the Unity engine that the editor is ignoring? Since each log entry has a different time stamp (milliseconds), the range difference being 157-170ms.
Is there a "best practice" in the Unity paradigm? Should the handler be async? Should the handler ignore subsequent calls within a certain window?
It seems like this would cause problems when I want to use a single click as a toggle on a hexagon tile.
Upvotes: 2
Views: 7540
Reputation: 11
For me, I had placed the Input.GetMouseButtonDown(0) inside FixedUpdate. Because of this, Input.GetMouseButtonDown(0) returns true multiple times in a single mouse click. Replace FixedUpdate with Update, and it will work.
Upvotes: 1
Reputation: 125455
This is a problem almost all new Unity programmers go through.
Input.GetMouseButton
is true
every frame when the mouse
Button is held down until released. Again, it will be true
every
frame until released.
Input.GetMouseButtonDown
is true
just once when the
mouse button held down. It will not be true
again until mouse is
released and pressed again.
In your case, it looks like you need Input.GetMouseButtonDown
which will only be true once and can only be true again when released and pressed again.
The-same thing applies to GetKey
, GetKeyDown
and GetKeyUp
.
Note:
If you use Input.GetMouseButtonDown
but it is still being called multiple times then make sure that your script is not attached to another or multiple GameObjects.
Upvotes: 15