- Home /
Trouble detecting button release with Input.GetButtonUp()
Hello!
I'm building a generic input management script that's supposed to listen for input, treat it and then output a state to the button. Trouble is Input.GetButtonUp() is not returning true when I let go of the buttons. In order for them to do so I need to spam both buttons of the same axis and then the game starts spewing log messages all of a sudden.
The updated code for the script is this:
using UnityEngine;
using System.Collections;
public class InputManager : MonoBehaviour
{
#region Raw input variables
private int button1Presses; //Holds the amount of times the button was pressed in between Time Segments;
private float button1HoldTime; //The amount of time the button was kept down in between Time Segments;
private float button1Axis; //Stores the Axis value of the button for the frame;
private int button2Presses;
private float button2HoldTime;
private float button2Axis;
#endregion
#region Treated input variables
private bool button1Pressed; //Indicates the button was pressed this Time Segment;
private bool button1DoubleTapped; //Indicates the button was double tapped this Time Segment;
private bool button1Held;//Indicates the button was held down this Time Segment;
private bool button1Released; //Indicates the button wasn't detected this Time Segment;
private bool button2Pressed;
private bool button2DoubleTapped;
private bool button2Held;
private bool button2Released;
#endregion
#region Miscellaneous control variables
private bool playerAway; //Variable indicating whether the player is away or not;
private float playerAwayTime; //Tracks how much time the player hasn't performed any input;
private int singlePressCount; //Number of presses the button must have to be considered a Press;
private int doubleTapCount; //Number of presses the button must have to be considered a DoubleTap;
private float holdTimeThreshold; //The amount of time the button must be held for it to be considered a Hold;
private float timeSegment; //The amount of time the game should wait before treating received input;
private float currentTimeSegment; //Variable used to track how much time's left before the game has to treat input;
#endregion
#region Initialization
void Start()
{
//Initializing raw input variables;
button1Presses = 0;
button1HoldTime = 0.0f;
button1Axis = Input.GetAxis("Button 1");
button2Presses = 0;
button2HoldTime = 0.0f;
button2Axis = Input.GetAxis("Button 2");
//Initializing treated input variables;
button1Pressed = false;
button1Held = false;
button1DoubleTapped = false;
button2Released = false;
button2Pressed = false;
button2Held = false;
button2DoubleTapped = false;
button2Released = false;
//Initializing miscelaneous variables;
playerAwayTime = 0.0f;
playerAway = false;
singlePressCount = 1;
doubleTapCount = 2;
holdTimeThreshold = 0.17f;
timeSegment = 0.2f;
currentTimeSegment = timeSegment;
}
#endregion
#region Update function
void Update()
{
//Catch input from keyboard, mouse and other relevant peripherals;
ListenInput();
//Read & treat received input;
if (currentTimeSegment <= 0.0f)
TreatInput();
else
currentTimeSegment -= Time.deltaTime;
}
#endregion
#region Custom functions
void ListenInput()
{
if (Input.anyKey)
{
playerAway = false;
playerAwayTime = 0.0f;
#region 'Button 1' detection
if (Input.GetButtonDown ("Button 1"))
{
//Debug.Log ("Button 1 Pressed!");
button1Presses += 1;
}
if (Input.GetButton ("Button 1"))
{
//Debug.Log ("Button 1 Held!");
button1HoldTime += Time.deltaTime;
}
if (Input.GetButtonUp ("Button 1"))
{
Debug.Log ("Button 1 Released!");
button1HoldTime = 0.0f;
}
button1Axis = Input.GetAxis("Button 1");
#endregion
#region 'Button 2' detection
if (Input.GetButtonDown ("Button 2"))
{
//Debug.Log ("Button 2 Pressed!");
button2Presses += 1;
}
if (Input.GetButton ("Button 2"))
{
//Debug.Log ("Button 2 Held!");
button2HoldTime += Time.deltaTime;
}
if (Input.GetButtonUp("Button 2"))
{
Debug.Log ("Button 2 Released!");
button2HoldTime = 0.0f;
}
button2Axis = Input.GetAxis("Button 2");
#endregion
}
else
playerAwayTime += Time.deltaTime;
}
void TreatInput()
{
currentTimeSegment = timeSegment;
#region 'Button 1' treatment
if (button1Presses == singlePressCount && button1HoldTime < holdTimeThreshold)
{
//Debug.Log ("Button 1 DETECTED PRESS!");
button1Pressed = true;
button1DoubleTapped = false;
button1Held = false;
button1Released = false;
}
else if (button1Presses >= doubleTapCount && button1HoldTime < holdTimeThreshold)
{
//Debug.Log ("Button 1 DETECTED DOUBLE TAP!");
button1Pressed = false;
button1DoubleTapped = true;
button1Held = false;
button1Released = false;
}
else if (button1HoldTime >= holdTimeThreshold)
{
//Debug.Log ("Button 1 DETECTED HOLD!");
button1Pressed = false;
button1DoubleTapped = false;
button1Held = true;
button1Released = false;
}
else
{
button1Pressed = false;
button1DoubleTapped = false;
button1Held = false;
button1Released = true;
}
button1Presses = 0;
button1HoldTime = 0.0f;
#endregion
#region 'Button 2' treatment
if (button2Presses == singlePressCount && button2HoldTime < holdTimeThreshold)
{
//Debug.Log ("Button 2 DETECTED PRESS!");
button2Pressed = true;
button2DoubleTapped = false;
button2Held = false;
button2Released = false;
}
else if (button2Presses >= doubleTapCount && button2HoldTime < holdTimeThreshold)
{
//Debug.Log ("Button 2 DETECTED DOUBLE TAP!");
button2Pressed = false;
button2DoubleTapped = true;
button2Held = false;
button2Released = false;
}
else if (button2HoldTime >= holdTimeThreshold)
{
//Debug.Log ("Button 2 DETECTED HOLD!");
button2Pressed = false;
button2DoubleTapped = false;
button2Held = true;
button2Released = false;
}
else
{
button2Pressed = false;
button2DoubleTapped = false;
button2Held = false;
button2Released = true;
}
button2Presses = 0;
button2HoldTime = 0.0f;
#endregion
}
#endregion
#region Get & Set functions
//Raw Input variables access functions;
public int GetButton1Presses()
{
return button1Presses;
}
public float GetButton1HoldTime()
{
return button1HoldTime;
}
public float GetButton1Axis()
{
return button1Axis;
}
public int GetButton2Presses()
{
return button2Presses;
}
public float GetButton2HoldTime()
{
return button2HoldTime;
}
public float GetButton2Axis()
{
return button2Axis;
}
//Treated Input variables access functions;
public bool GetButton1Pressed()
{
return button1Pressed;
}
public bool GetButton1DoubleTapped()
{
return button1DoubleTapped;
}
public bool GetButton1Held()
{
return button1Held;
}
public bool GetButton2Pressed()
{
return button2Pressed;
}
public bool GetButton2DoubleTapped()
{
return button2DoubleTapped;
}
public bool GetButton2Held()
{
return button2Held;
}
//Miscellaneous variable access functions;
public float GetPlayerAwayTime()
{
return playerAwayTime;
}
public bool GetPlayerAway()
{
return playerAway;
}
public void SetPlayerAway(bool playerAwayValue)
{
playerAway = playerAwayValue;
}
#endregion
}
Right now, the main output of this script is in the console. This is messing my hold event detection, because since Input.GetButtonUp() is not returning true, the variable is not being reliably reset to zero. As a result, some presses or double taps come off as holds. Any ideas?
FixedUpdate
and Update
are not guaranteed to run in any order or amount at runtime. At some points you might get 10 Update
calls and not a single FixedUpdate
call, while at other times you'll get 2 FixedUpdate
calls and just one Update
. Since you're using Time
anyway (and aren't relying on FixedUpdate
for ti$$anonymous$$g), there is no point in using FixedUpdate
and it might even cause problems later on, when you need more accurate Input
.
You should have nothing in FixedUpdate except physics code. It's not intended for anything else.
So I should just ditch the FixedUpdate() function for this particular implementation and rely solely on the Update() funcion while continuing to perform all my time checks internally with custom variables?
If that's the case, that's kind of bad news. I'm sure I can come up with an implementation along those lines, but I was hoping to salvage most of what I have here. Well, I'll give it a whirl and let you know how I fared. Thanks for help!
With the way it's currently written you should be able to call TreatInput
in Update
and it should still work
Yeah, I think I see it... I'll try calling it within a timer check, so it only defines the state of the button after the time segment. Thanks guys, much appreciated!
On the FixedUpdate() function thing: I really thought I could use it as a timed version of Update(). Guess I was wrong. Thanks for the heads up guys!
UPDATE: Original question was changed as instructed by veteran user.
Answer by Junjokar · Dec 31, 2013 at 03:52 AM
I just figured out the issue after staring at the problem for another 3 hours:
The problem is in the use of Input.anyKeys as the conditional for that section of code within the ListenInput() function.
When you release a key and has none other pressed, Input.anyKey will return false and the Input.GetButtonUp if statement will never get a chance to run. That's why it would work if you pressed the buttons alternatively, because then at least one other button would be pressed and the line of code would run. The ListenInput() function should be as this:
void ListenInput()
{
if (Input.anyKey)
{
playerAway = false;
playerAwayTime = 0.0f;
#region 'Button 1' detection
if (Input.GetButton ("Button 1"))
{
//Debug.Log ("Button 1 Held!");
button1HoldTime += Time.deltaTime;
}
else if (Input.GetButtonDown ("Button 1"))
{
//Debug.Log ("Button 1 Pressed!");
button1Presses += 1;
}
button1Axis = Input.GetAxis("Button 1");
#endregion
#region 'Button 2' detection
if (Input.GetButton ("Button 2"))
{
//Debug.Log ("Button 2 Held!");
button2HoldTime += Time.deltaTime;
}
else if (Input.GetButtonDown ("Button 2"))
{
//Debug.Log ("Button 2 Pressed!");
button2Presses += 1;
}
button2Axis = Input.GetAxis("Button 2");
#endregion
}
else
{
#region 'Button 1' Detection
if (Input.GetButtonUp("Button 1"))
{
Debug.Log ("Button 1 Released!");
button1HoldTime = 0.0f;
}
#endregion
#region 'Button 2' Detection
if (Input.GetButtonUp ("Button 2"))
{
Debug.Log ("Button 2 Released!");
button2HoldTime = 0.0f;
}
#endregion
playerAwayTime += Time.deltaTime;
}
}
Hopefully this will help anyone else with this issue in the future. Cheers!