- Home /
How to treat Input.GetAxis as Input.GetButtonDown?
The triggers on xbox controller are axis, and when switching between mouse triggers and xbox, they do not behave the sameway, because the xbox triggers are basically Input.GetButton, which causes the firing of weapons to shoot repeatedly.
I tried Input.GetAxisRaw and nothing changed.
You can just use GetButtonDown with the name of an axis.
Answer by CodeMasterMike · Jan 08, 2013 at 10:16 AM
With the GetAxisRaw function you get either 0 or 1/-1 (depending on axis). So it does work like the GetButton function. If you want it to work as the GetButtonDown function, you need to add little more code.
private bool m_isAxisInUse = false;
void Update()
{
if( Input.GetAxisRaw("Fire1") != 0)
{
if(m_isAxisInUse == false)
{
// Call your event function here.
m_isAxisInUse = true;
}
}
if( Input.GetAxisRaw("Fire1") == 0)
{
m_isAxisInUse = false;
}
}
In this very simple example, you see that the event function will be called once, eventhough the axis-button keeps being pressed down. And when the axis-button is no longer pressed, the check gets restored, so that next input it will fire your event function again. I hope this example helps you.
Good luck!
how would this look in unityscript? and what do you put for axis in use? do you leave it as is, or do you really put the axis in use there? like m_9thAxis?
I don't know unityscript, but if you follow the thread of thought, Im sure you can rewrite it to unityscript, since its not a complicated code:
If your GetAxisRaw("Fire1") is pressed AND your "button is in use" is set to false, then set your "button is in use" boolean to true and do whatever you want to do when the button is pressed.
if your GetAxisRaw("Fire1") is NOT pressed, then set your "button is in use" boolean to false.
You can call the boolean variable whatever you want. If you have several buttons that you want handle like above, then you would need to rename them to something properly, yes.
Easiest to make and read would be something like:
m_Fire1IsInUse m_Fire2IsInUse m_SpaceIsInUse etc. etc.
There are always ways making the code more dynamic without having to hard code all variables, and so on. But that is more advanced topic.
Simple and useful answers always makes me happy. Thanks for this useful advice Code$$anonymous$$aster$$anonymous$$ike.
I am getting a "cannot implicitly convert type float to bool" error when implementing this. "fire 1" in my case is a bool. Do I just HAVE to recode some stuff and configure it to be a float since I am using an axis? I was using the Right Bumper on an xbox pad, but want the right trigger to do the job ins$$anonymous$$d. GetButtonDown worked perfectly with the bumper. Advice real quick? :D
Re coding everything to be a float vs a bool worked perfectly. thanks!
Answer by AndrewRyan · Feb 09, 2017 at 06:12 PM
I wasn't satisfied with this answer, so I devised this solution which I think is cleaner and modular and uses event delegates:
//left trigger
bool _lt;
public delegate void LeftTrigger();
public event LeftTrigger onLeftTrigger;
void LTrigger()
{
if(!_lt && Input.GetAxis("360_Triggers") < 0f)
if(onLeftTrigger != null) onLeftTrigger();
_lt = true;
while(Input.GetAxis("360_Triggers") < 0f && _lt) return;
_lt = false;
}
void Update()
{
LTrigger();
}
Answer by Julianobsg · May 18, 2018 at 11:29 PM
I saw both answers recently, but wasn't happy with any of the given answers, in the documentation I found the value anyKeyDown So I managed to get a cleaner solution for me:
void Update()
{
if(Input.anyKeyDown)
{
float horizontal = - Input.GetAxis("Horizontal");
}
}
Tried this method, since I agree that it looks cleaner. However, it only works for the keyboard and does not extend to controller input.
Answer by KelvinRodri · Sep 02, 2018 at 11:58 PM
I was not so happy with those solutions, and I think that could exist one that is clear to read and easy to reuse. So I did the following code:
using UnityEngine;
public abstract class BaseJoystickInputs : ScriptableObject {
bool _lastInputAxisState;
/// <summary>
/// Gets the axis input like an on key down event, returning <c>true</c> only
/// on the first press, after this return <c>false</c> until the next press.
/// Only works for axis between 0 (zero) to 1 (one).
/// </summary>
/// <param name="axisName">Axis name configured on input manager.</param>
protected bool GetAxisInputLikeOnKeyDown(string axisName)
{
var currentInputValue = Input.GetAxis(axisName) > 0.1;
// prevent keep returning true when axis still pressed.
if (currentInputValue && _lastInputAxisState)
{
return false;
}
_lastInputAxisState = currentInputValue;
return currentInputValue;
}
}
Please let me know any doubts/suggestions.
@JamesG$$anonymous$$arks hello, idk if you have found your solution, but maybe this can help.
Answer by tombueng · Sep 18, 2019 at 08:32 PM
using System.Collections.Generic; using UnityEngine;
public class MyInput {
private static Dictionary<string,float> lastDict = new Dictionary<string, float>();
public enum Dir { POSITIVE, NEGATIVE }
public static float wait = 0.4f; //min time to wait between returning true 400ms
public static float switchvalue = 0.8f; //how deep do we need to press
public static bool repeat=true;
//shortcuts
public static bool GetAxisAsButtonNegative(string axisName) => GetAxisAsButton(axisName, Dir.POSITIVE);
public static bool GetAxisAsButtonPositive(string axisName) => GetAxisAsButton(axisName, Dir.NEGATIVE);
public static bool GetAxisAsButton(string axisName, Dir direction)
{
float value = Input.GetAxis(axisName);
string key = axisName + "." + direction; //key for the dictionary
float last = 0;
lastDict.TryGetValue(key, out last); //last time we returned "true" for this query
float dur = Time.time - last; //time since we returned "true" for this query
//not pressed, reset wait time to be able to "press" this button repeatedly and faster as wait
if (Mathf.Abs(value) < switchvalue/2f)
{
lastDict[key] = 0;
return false;
}
//waiting time between pressed already passed (repeat mode) or button already had been released (no repeat mode)?
if ((dur > wait && repeat) || (!repeat && last==0)) {
//retrun true axis is in the matching direction
if (direction == Dir.NEGATIVE && value < -switchvalue || direction == Dir.POSITIVE && value > switchvalue)
{
//save time
lastDict[key] = Time.time;
return true;
}
} else
{
//must still wait, call again in next loop
}
return false;
}
}
I really like this implementation. Thanks for sharing that. Very elegant and flexible