Input: Mixing axis and buttons (ie: Input.GetAxis versus Input.GetButton)

In my game, I use the vertical and horizontal axis (as defined by default in InputManager) in order to control my character.

However, I’d like to be able to use the GetButton functions for the positive/negative keys for the Vertical axis along with using GetAxis to get an analog value. Is there a way to do this?

So in other words, in some parts of my code I do this:

throttle = Input.GetAxis("Vertical") ;

But then I would like to do this, too:

if (Input.GetButtonDown (???))   
// where ??? would be Vertical's positive button (plus the alt button)

This works for what you need. This is for a cursor I made.

void Update()
{   
    	if (toggleOn == true)
    		{
    	if (Input.GetAxis ("Vertical") > 0)
    			{
    				cursormove += 20;
    				toggleOn = false;
    			}
    	if (Input.GetAxis ("Vertical") < 0)
    			{
    				cursormove -= 20;
    				toggleOn = false;
    			}
    		}
    
            // do stuff
    
    	if (Input.GetAxis ("Vertical") == 0)
    			{
    				toggleOn = true;
    			}
}

I had the idea to just write a button-press simulator on my own, but then I ran into the problem of making sure that I get these changes to my scripts in a timely fashion. Doing a ButtonDown or Up event requires tracking the state of the input across a frame.

So, in short I would do this:

  1. Read state of axis, generate the appropriate button up/down states
  2. Do my usual Update logic that relies upon these states.
  3. Repeat per frame.

Unfortunately, Unity only provides us with a way to delay per-frame processing (via LateUpdate) but no way to do processing before a frame begins. (ie: No PreUpdate.) Therefore, step #1 is never guaranteed to be complete before step #2. (Which can run in any order, AFAIK, though I haven’t tested this rigorously but it just makes sense.)

I could do step #1 in step #2 for each time I want to use these inputs, ie: such as…

void Update()
{
  InputLibrary.assignAxisButtonStates ("Vertical") ;

  if (InputLibrary.GetAxisAsButton ("Vertical", InputLibrary.UpButton))
  {
     // equiv to Input.GetButton()
     // ie: Vertical is currently in positive analog range
  }

  if (InputLibrary.GetAxisAsButtonDown ("Vertical", InputLibrary.UpButton))
  {
    // equiv to Input.GetButtonDown()
    // ie: Vertical was shifted from dead zone to positive analog range since last frame
  }

  if (InputLibrary.GetAxisAsButtonUp ("Vertical", InputLibrary.UpButton))
  {
    // equiv to Input.GetButtonUp()
    // ie: Vertical was shifted from positive analog range to dead zone since last frame
  }
}

But it’s a little ugly. assignAxisButtonStates would need to keep track to make sure it isn’t called multiple times per frame.

Input.GetAxis gives a value more than 0 if being pressed and a negative value if not so you could use

if (Input.GetAxis("Vertical") < 0){
//GO BACK GODE
}
if (Input.GetAxis("Vertical") > 0){
//GO FORWARD GODE
}

or you could do what many people do which is just move to the direction of the axis, for example

transform.Translate(0,0, Input.GetAxis("Vertical");

based off of this answer http://answers.unity3d.com/questions/376587/how-to-treat-inputgetaxis-as-inputgetbuttondown.html

You can use Input.GetAxisRaw

to get button states like so:

if(Mathf.Approximately(Input.GetAxisRaw("Horizontal"), -1))
{
	//Left
}
else if(Mathf.Approximately(Input.GetAxisRaw("Horizontal"), 1))
{
	//Right
}

this works because no smoothing is applied to GetAxisRaw, so if you are holding your key you get that value (I used Mathf.Approx because they are floats and might not be exactly -1/1 just in case)