- Home /
Find out if any Button on any Gamepad has been pressed and which one
Hi
The title pretty much says it all. I want my players to be able to assign custom gamepad buttons for the controls. So imagine you click on "jump" and a message says "press the key for jump", after which you press that key, the game remembers which one it was and you can use the new setting from then on.
To do that for a keyboard is easy, since I only have to call
public void OnGUI ()
{
if (Event.current.type == EventType.KeyDown) {
KeyCode code = Event.current.keyCode;
[...]
to find out what was pressed and it is very easy to work with that KeyCode.
For gamepads however there does not seem to be such an event. The only option I have found so far is to poll
if (Input.GetKeyDown ("joystick 1 button 0"))
for each button on each gamepad during each update(), which seems very bloated and certainly not right.
Does anyone know an easier way to catch any button that has been pressed?
I know it's an old question but you can set up the buttons in the "input" menu and call the input name ins$$anonymous$$d of the "joystick 1..."
Did you ever figure out how to do this? I'm curious, myself.
http://answers.unity3d.com/questions/755304/how-do-you-read-or-get-info-from-an-input-from-a-j.html
it doesnt take much processor to monitor all changes in all axes and buttons from joypad using:
if (button1value != lastbutton1vaulue){button1Changed == True; lastButtonValue = button1value}else{button1changed = false;}
a slight variation of that is to make a variable anybuttonHasChanged... and any time any button changes, that value becomes true for a frame. you also have to make small exceptions in case 2-3 buttons change in a single frame, i.e. pad1 and axis1,
it's fine to scan all buttons on gamepad, it wouldnt be much different from a magic function which scans all buttons on gamepad./
Answer by drudiverse · Jul 24, 2014 at 10:25 AM
No there isnt an any button option, but if you need to find which one, you have to monitor them all anyway...
writing IF is actually the most efficient way of writing an multiplex for scanning IO values, it seems abit long but it's very efficient, IF statements are less taxing than even a single + arithmetic to the processor. so it's like every frame you are adding 20 plus arithmetics it's pretty cool.
In the end I did exactly this, details here http://answers.unity3d.com/questions/755304/how-do-you-read-or-get-info-from-an-input-from-a-j.html#answer-760740 so for future readers; this seem to be correct unfortunately.
FIrstly, I'd like to see you back up your statement that flow control statements are somehow "faster" than addition operations.
The .NET compiler tends to optimize things better if there is LESS flow control, and smaller function sizes. What's more, a single if statement can easily (and often does) turn into a branch, which can be mispredicted by the CPU, resulting in a much longer time waiting than a single addition statement.
While, to the best of my knowledge, most CPUs and popular language implementations (such as .NET C#) get somewhere in the order of 99%+ correct branch prediction, that 1% is so costly it's still well worth it to just NOT use if statements where you don't need to.
That being said, replacing addition operations with if statements should not be done for optimization (even if it did somehow make the operation faster... which in the VAST majority of cases it will certainly NOT). This would be a micro-optimization, and wouldn't stand to improve overall performance by any amount significant enough that a human could even notice it short of spitting out the microseconds per frame.
TLDR:
If statements are not faster than addition, and are often $$anonymous$$UCH slower. Don't micro-optimize. Follow the 3-step hierarchy of code writing -- Functionality comes first, then readability, then performance.
Only if performance becomes such a problem that it actually begins to affect functionality should you EVER consider altering code to improve its performance at the cost of readability.
The best option is to write a library for this, so everyone who needs to use it doesn't have to write the code themselves. (it would return a $$anonymous$$eyCode
corresponding to the pressed key)
Answer by ayrrik · Sep 30, 2015 at 09:05 AM
for (int i = 0;i < 20; i++) {
if(Input.GetKeyDown("joystick 1 button "+i)){
print("joystick 1 button "+i);
}
}
This code working for me, thank you, ayrrik! ( USB Joystic Esperanza EG102 )
I can't comment on @ayrrik's post, but I noticed an error in his answer code. The problem is that you can't directly concatenate strings and integers. You have to use integer_variable_name.toString()
to convert it to a string. So here's the fixed snippet:
for (int i = 0; i < 20; i++) {
if (Input.Get$$anonymous$$eyDown("joystick 1 button "+i.toString())) {
// do something
}
}
@canine828 what are you talking about? Of course you can!
Huh. I wasn't able to before... $$anonymous$$aybe the sysad$$anonymous$$ moved it? Or... OH! It must have been that I wasn't signed in when I first clicked it, then I signed, in, then I pressed the Back button to get back here, and then I wasn't able to, and then I refreshed it, and then I posted! Or something like that...
I think @Lohoris2 was referring to the fact that you can indeed concatenate a string and integer without calling ToString.
Answer by Frosting · Mar 25, 2016 at 05:51 PM
Hello,
I may help someone. I am using Logitech Wireless GamePad F710.
Here detection pressed button:
void Update () {
if (Input.GetKeyDown(KeyCode.JoystickButton0)) {
Debug.Log("wohoo!!");
}
}
Here description of buttons of this Gamepad:
JoystickButton0 - X
JoystickButton1 - A
JoystickButton2 - B
JoystickButton3 - Y
JoystickButton4 - LB
JoystickButton5 - RB
JoystickButton6 - LT
JoystickButton7 - RT
JoystickButton8 - back
JoystickButton9 - start
JoystickButton10 - left stick[not direction, button]
JoystickButton11 - right stick[not direction, button]
Answer by varumora · Apr 08, 2016 at 06:42 AM
Actually there is an "anyKey" option, but you still have to iterate for every keyCode:
if (Input.anyKey)
{
foreach(KeyCode kcode in Enum.GetValues(typeof(KeyCode)))
{
//do something with kcode
}
}
i did this too, this tests all possible keycodes in the enum "$$anonymous$$eyCode" and prints if it has been pressed. This can be used to assign inputs as $$anonymous$$eycodes, or you can cast it to strings inputs if you know how.
System.Array values = System.Enum.GetValues(typeof($$anonymous$$eyCode));
foreach($$anonymous$$eyCode code in values){
if(Input.Get$$anonymous$$eyDown(code)){ print(System.Enum.GetName(typeof($$anonymous$$eyCode), code)); }
}
but i am still searching how to parse the axis...
Answer by MelonHeadStudios · May 16, 2015 at 10:18 PM
So after Extensive thinking, I believe I have found the answer to this long standing problem. here's the code--- You need a string variable Called CONFIGBUTTONS2 for this instance to work.
var Numbers1 = new Array (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
for (var go1 : float in Numbers1) {
if(Input.GetKeyDown("joystick 1 button "+go1)){CONFIGBUTTONS2 = "joystick 1 button "+go1;}
if(Input.GetKeyDown("joystick 2 button "+go1)){CONFIGBUTTONS2 = "joystick 2 button "+go1;}
if(Input.GetKeyDown("joystick 3 button "+go1)){CONFIGBUTTONS2 = "joystick 3 button "+go1;}
if(Input.GetKeyDown("joystick 4 button "+go1)){CONFIGBUTTONS2 = "joystick 4 button "+go1;}
if(Input.GetKeyDown("joystick 5 button "+go1)){CONFIGBUTTONS2 = "joystick 5 button "+go1;}
if(Input.GetKeyDown("joystick 6 button "+go1)){CONFIGBUTTONS2 = "joystick 6 button "+go1;}
if(Input.GetKeyDown("joystick 7 button "+go1)){CONFIGBUTTONS2 = "joystick 7 button "+go1;}
if(Input.GetKeyDown("joystick 8 button "+go1)){CONFIGBUTTONS2 = "joystick 8 button "+go1;}
}
var Numbers2 = new Array ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
for (var go2 : String in Numbers2) {
if(Input.GetKeyDown(go2)){CONFIGBUTTONS2 = go2;}
}
So this script checks through all the buttons on 8 separate joysticks and returns it in the form of the String CONFIGBUTTONS2. So if you want to assign that to an input button, just assign the value of CONFIGBUTTONS2 to another variable like ABUTTON. then use that ABUTTON in...
if(Input.GetKey(ABUTTON)){
//do something
}
I have yet to find a way to easily find all the Input Axis's, but those aren't nearly as complicated as the 150+ joystick buttons. Hope this Helps!