How can I know that any button on gamepad is pressed?

To know if any keyboard key is pressed we can useKeyboard.current.anyKey.isPressedbut there is no function like this in Gamepad.current.

How can I know that any button is pressed on the current gamepad?

PS.
I tried using Gamepad.current.IsActuated(0.2f) but is always TRUE (with any threshold value)

ATM there’s no equivalent to the keyboard’s “anyKey” for gamepads. Makes me wonder whether we should actually adapt AnyKeyControl to be AnyButtonControl and add that to more devices. Could be useful.

Anyway. In code, one alternative way is to do

var gamepadButtonPressed = Gamepad.current.allControls.Any(x => x is ButtonControl button && x.isPressed && !x.synthetic);

Unrolling it into a for loop will avoid GC heap garbage.

It should only be true as long as there is some state on the gamepad that isn’t at default value. In practice, that will, however, almost always be the case (sticks are rarely at exact zero, for example). Overall, there’s currently no meaningful definition of a whole device being actuated. So it uses the default definition which is just that it’s state is not at default.

2 Likes

@Rene-Damm Indeed, an “anyKey” on keyboard/gamepad/whatever would be really usefull ! Atm I can’t use the autoswitch of PlayerInput (it just bugs or idk, related to VR always sending input probably), so being able to do the “autoswitch” myself with a anyKey binding would be super usefull !

While not super efficient, there are ways in which you can bind to all buttons or all controls on a device even without a dedicated control for that.

To do that, you need to switch the “Path” property to text mode using the little T button on the right. With that, you have access to the path language directly which allows for writing more expressions than the control picker can currently generate.

Some examples.

// Bind to all toplevel buttons on the left-hand XR controller.
<XRController>{LeftHand}/<Button>

// Bind to all toplevel controls on the right-hand XR controller.
<XRController>{RightHand}/*

Would like to know more about the problems here. Sorry if I missed something you already posted somewhere else. Still catching up.

1 Like

No problem, so basically what I’m doing :

I’m using version 0.9.6 of the input system (because nothing works if I go to 1.0 due to the gamepad/xr parts that got removed).

I’m using PlayerInput, but stuck with using “Send message” as Invoke Unity Event is still broken (someone from Unity said it should be fixed in 2019.2.8f but it’s still broken for me).

I’m able to toggle between VR/Non-VR (gamepad or mouse/keyboard) with the “isTracked” action + XRDevie.userPresence, so I automatically switch by putting on the VR headset. For that, I added the headset as optionnal device to all Non-VR control scheme

I’m listening to InputUser.onChange to modify everything I need between VR/Non-VR.

I’m currently facing 2 problems :

  1. if I toggle the auto-switch on PlayerInput, VR control scheme gets set everyframe even without the headset / controllers moving or doing anything, my guess is that it’s always sending inputs no matter what, so PlayerInput is switching to this ?

  2. to be able to switch BACK to VR, I need to do this

_playerInput.defaultControlScheme = "VR";
_playerInput.enabled = false;
_playerInput.enabled = true;

if I don’t, both controllers are not tracked anymore. Buttons/Joystick works fine, but no position/rotation tracking.

I can give you the full code of my Player if needed.

Edit : Using /* and /* works fine ! I’m able to switch “automatically” now :slight_smile:

Thank you for the details.

Sorry about that. I know that the fix has made it out in 2019.3b4 but I’m not sure about the state of the backport to 2019.2. All I know is it did happen so should make it out eventually… :confused:

A likely cause of that is controls missing a noise flag. The system relies on controls that give noisy input on being marked explicitly. If a noisy control (such as orientation) is missing that flag, the system will think there’s valid user input on the control. Let me go and talk to the XR guys about that.

Could you file a ticket through the Unity bug reporter and attach the project? What you describe definitely sounds buggy and we should have closer look.

No problem, just a bit annoying with the SendMessage (and that I will need to rewrite every action :p)

Don’t know if it’s that you’re referring to, but I tried checking the “Filter noise on current” in the project settings / input system package, but it did nothing. (btw, UI is weird here, can’t read all the text).

I’m doing it and will post the case number here, thanks !

EDIT : Case #1190144

Every control has a noise flag (in the API, that determines the value of InputControl.noisy). This flag has to be set by the “layout”, i.e. the data for a specific device. In this case, the XR layout builder is responsible for setting these flags.

The code that detects control scheme switches will ignore any input that happens to come from a control that’s marked as noisy. This will prevent, for example, a control scheme switch to trigger from the gyro on a PS4 gamepad.

If a layout isn’t setting these flags correctly, the control scheme switching code will mistake noise for real input and initiate spurious control scheme switches. That’d be a bug in how a specific device is wired up for the new input system.

Oh ok, so I cannot modify this on my end ?

That’s weird nobody encountered that before, but I guess there is not a lot of people doing VR/Non-VR project anyway.

Posted the case number in the previous post. Thanks again

It is possible to fix up / modify layouts using “layout overrides”. Which can be used to retroactively set the noisy flag.

InputSystem.RegisterLayoutOverride(@"
    {
        ""name"" : ""MyOverrides"",
        ""extend"" : ""NameOfLayoutYouWantToModify"",
        ""controls"" : [
            { ""name"" : ""nameOrPathOfControlToModify"", ""noisy"" : true }
        ]
    }
");

(NB: There were some bugs in the layout override code which are fixed on latest develop and will be in the next package; but yeah, means you’d potentially run into some issues on 0.9.6)

I’ll make sure we address it on our side (if this is indeed the problem; could also be something else).

Yeah, I’ll stick with my solution for the moment then, it’s working fine.

Is there also a way to get “any axis on the gamepad that are over 0.2 in intensity”?

Or even “any gamepad axis”?

An ‘Any Button’ or ‘Any Axis’ would be super helpful, as right now it seems impossible to recreate something like this for gamepad or mouse input. The code snippet alternative provided early on in this post no longer works.

Indeed. It’s in the works and hopefully will make it for 1.1 final. A partially complete implementation adds a API like this

InputSystem.onAnyButtonPressCallOnce +=
    button =>
    {
        Debug.Log($"Button {button} was pressed");
    };

ATM the quickest way to make it happen is to either rely on InputUser for this (which, however, only works for devices not paired to any player):

++InputUser.listenForUnpairedDeviceActivity;
InputUser.onUnpairedDeviceUsed +=
    (control, eventPtr) => { ... };

or to hook into InputSystem.onEvent (which is relatively quick but not efficient):

InputSystem.onEvent +=
    (eventPtr, device) =>
    {
        if (!eventPtr.IsA<StateEvent>() && !eventPtr.IsA<DeltaStateEvent>())
            return;

        var controls = device.allControls;
        foreach (var control in controls)
        {
            if (!(control is ButtonControl button))
                continue;
            if (button.ReadValueFromEvent(eventPtr) > InputSettings.defaultButtonPressPoint)
            {
                Debug.Log($"Button {button} pressed");
                break;
            }
        }
    };

An API to do these kind of event queries a lot more efficiently is in the works (both RebindingOperation and InputUser currently have performance problems related to this).

1 Like

Hi, will this apply to the mouse as well? I have a tutorial dialog that I want to go away on any input other than things like analog stick deflection or mouse movement.

Thanks Rene!

I wonder if there’s any new way to do it in the latest publicly preview version of the package, as per today (guess it’s 1.1.0.preview.2?)

That’s quite some boilerplate to get “AnyKey for Any Device”.

Which would be used on most splash screens.

Sorry for the somewhat necrobump.

Gamepad.allControls doesn’t seem to be documented anywhere in the gamepad scripting API reference?
I may have missed it but I couldn’t find it in any version of the documentation.
Additionally, the 1.0.2 input system doesn’t contain a definition for Gamepad.current.allControls.Any

Anyone know how to effectively check for any gamepad input as of Input System v1.0.2?
Searching the forums failed me this time…

Edit : This very verbose code snippet seems to work. For any practical use, a more elegant solution like Keyboard.current.anyKey would be more convenient though.

        for (int i = 0; i < Gamepad.current.allControls.Count; i++)
        {
            var c = Gamepad.current.allControls[i];
            if (c is ButtonControl)
            {
                if (((ButtonControl)c).wasPressedThisFrame)
                {
                    Debug.Log("Using Pad");
                }
            }
        }
4 Likes

Definitely not a necrobump - I’m still on the development and now basically still facing the same issue, but pertaining racing Wheel devices.

Which - are seen as Joysticks for some reason.

I wish there was a way to just “get the break pedal value” instead of having to buy each and every wheel on the market to make sure it’s mapped to rx, z, y, or whatever else axis (also, why are they unpressed at 1, half pressed at 0, and fully pressed at -1? A pedal?).

I read wheel support has been cut away from the IS and added back to some other major change but - I’d need it working now, and on PC/XBOX S|X, PSx, etc. :stuck_out_tongue:

Also, a non-reactive wheel is a wheel which -could- be left as turned 90 degrees - which makes it a bit harder to determine whether it’s actually being used now or just being plugged in and forgot :stuck_out_tongue:

Any update on this @ ?

Gamepad.current.allControls.Any

“Any” does not seem to be implemented in the curent version of the Input System.

As for this snippet, if anyone (like me) couldn’t get this to work at first, it requires the “InputSystem.Controls” namespace be added.

InputSystem.onAnyButtonPress.Call(
    ctrl =>
    {
        if (ctrl.device is Gamepad gamepad)
            Debug.Log($"Button {ctrl} on {device} was pressed");
    });
1 Like