IAbstract
IAbstract

Reputation: 19881

Unity Input detected multiple times in a press

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

Answers (2)

Deepak Munagala
Deepak Munagala

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

Programmer
Programmer

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.

enter image description here

Upvotes: 15

Related Questions