Open bcolloran opened 2 years ago
What gamepad are you using? This is probably an upstream bug in gilrs.
It's an XBox Wireless Controller.
Sorry if I've filed this in the wrong place! Does anyone on the bevy team have permissions to transfer the issue over there? (I can file it manually if not)
(fwiw while we sort out the right place for this issue)--
using: axes.get(GamepadAxis(gamepad, GamepadAxisType::RightZ))
with axes: Res<Axis<GamepadAxis>>
rather than: button_axes.get(GamepadButton(gamepad, GamepadButtonType::RightTrigger))
with button_axes: Res<Axis<GamepadButton>>
does the trick for getting the trigger analog values.
(the gamepad_input
example uses the latter)
Ah! Looks like #5220 but for triggers. This is probably not terribly hardware specific, and is mostly our problem.
We should look to see if the same style of fix can be applied.
On bevy 0.8.1 I have the same issue. With all of the following controllers: -wired XBox One -wired XBox 360 -wired and wireless dualshock 4 (PS4) -wired and wireless dual sense (PS5) (the playstation controllers are using ds4windows so they show up as xinput devices, specifically 360 controllers I believe)
The issue is the same in all cases. Left and right stick analog values report correctly but right and left triggers only act as buttons (analog values for RightZ and LeftZ are always 0.0).
I am using:
using: axes.get(GamepadAxis(gamepad, GamepadAxisType::RightZ)) with axes: Res<Axis
>
as @bcolloran mentioned.
For what it's worth, I couldn't reproduce it until I updated my xpadneo driver to the latest version which mostly consists of this product code change I believe.
Basically, old version: SteamInput messed up, input in Bevy works. New version: SteamInput works, input in Bevy messed up.
@Carlrs, I suspect gilrs
was working around a bad driver. Can you open an issue upstream?
From what I've been testing, wired XBox One controller seems to be working fine now in bevy 0.9.1 (haven't tested earlier versions). I did see a few issues in the gilrs repo that are tangentially related and have been fixed by the latest version of gilrs, as used by latest bevy. @RaddHazard: is this also fixed for you?
@rdelfin Updated quickly and it looks like I have the same problem. Triggers only working as buttons, no analog values.
I fell into a rabbit hole on this one a little bit... hopefully something in here is useful.
TL;DR:
My understanding is that button_axes.get(GamepadButton(gamepad, GamepadButtonType::RightTrigger2))
(notice the 2
)
with button_axes: Res<Axis<GamepadButton>>
is the correct way to get the trigger's analog value in bevy. GamepadButtonType::RightTrigger
(no 2
) is the right bumper on xbox 360 controllers.
My investigation (see "Research" section) leads me to believe that (at least on linux) GamepadAxisType::LeftZ
and GamepadAxisType::RightZ
are supposed to be representing a 3rd dimension for the left and right stick. Looking around, I think this may be used for joysticks that can also twist.
In reality, I think different gamepad drivers do different things, some map triggers to LeftZ/RightZ. Then gilrs (using SDL gamecontrollerdb.txt
) remaps them to the "right" place, as analog buttons. So if you're seeing trigger values in LeftZ/RightZ, it's probably missing or misconfigured in SDL gamecontrollerdb.txt
: https://github.com/gabomdq/SDL_GameControllerDB/blob/master/gamecontrollerdb.txt
To see some more info about what gilrs is doing with your controller:
Add to Cargo.toml
:
[dependencies]
gilrs = "0.10"
uuid = "1.3"
Put in an existing rust file and app.add_system(output_gamepad)
:
use gilrs::{Axis, Button, Gilrs};
use uuid::Uuid;
fn output_gamepad(gilrs: NonSend<Gilrs>, mut printed: Local<bool>, mut counter: Local<u8>) {
if !*printed {
// This is *not* the right way to interact with gamepads in bevy, you shouldn't be using gilrs directly.
for (_, gamepad) in gilrs.gamepads() {
println!("uuid: {:?}", Uuid::from_bytes(gamepad.uuid()));
println!("uuid (no '-'): {:?}", Uuid::from_bytes(gamepad.uuid()).to_string().replace("-", ""));
println!("os_name: {:?}", gamepad.os_name());
println!("map_name: {:?}", gamepad.map_name());
println!("mapping_source: {:?}", gamepad.mapping_source());
println!("LeftZ maps to: {:?}", gamepad.axis_code(Axis::LeftZ));
*printed = true;
}
}
*counter = (*counter).wrapping_add(1);
if *counter % 60 == 0 {
for (_, gamepad) in gilrs.gamepads() {
// This is *not* the right way to get theses values in bevy, you shouldn't be using gilrs directly.
println!("LT: {:?}", gamepad.button_data(Button::LeftTrigger).map(|b| b.value()));
println!("LT2: {:?}", gamepad.button_data(Button::LeftTrigger2).map(|b| b.value()));
}
}
}
The output for my Microsoft Xbox 360 Wireless Controller on linux:
uuid: 03000000-5e04-0000-a102-000000010000
uuid (no '-'): "030000005e040000a102000000010000"
os_name: "Xbox 360 Wireless Receiver"
map_name: Some("Xbox 360 Controller")
mapping_source: SdlMappings
LeftZ maps to: None
LT: None
LT2: None
LT: None
LT2: Some(0.85490197)
LT: None
LT2: Some(0.77254903)
LT: None
LT2: Some(0.627451)
LT: None
LT2: Some(1.0)
LT: None
LT2: Some(1.0)
LT: None
LT2: Some(0.0)
Searching for the uuid in https://github.com/gabomdq/SDL_GameControllerDB/blob/master/gamecontrollerdb.txt gets me:
030000005e040000a102000000010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
Note the Linux
at the end, this mapping will only be used by gilrs when building on linux (technically: "unix that's not Android and not MacOSX", so maybe BSDs and such as well?). See https://gitlab.com/gilrs-project/gilrs/-/blob/master/gilrs/build.rs .
https://gitlab.com/gilrs-project/gilrs/-/blob/b17de7da57485c41595c17990965e1ad7b7a2c56/gilrs/src/mapping/mod.rs#L108
maps gilrs_core::native_ev_codes::AXIS_LEFTZ
to gilrs::Axis::LeftZ
https://gitlab.com/gilrs-project/gilrs/-/blob/7cd001dacfb188405e5e41520912a259367a4703/gilrs-core/src/lib.rs#L304
defines gilrs_core::native_ev_codes::AXIS_LEFTZ
as gilrs_core::platform::native_ev_codes::AXIS_LEFTZ
When compiled on linux:
https://gitlab.com/gilrs-project/gilrs/-/blob/7cd001dacfb188405e5e41520912a259367a4703/gilrs-core/src/platform/linux/gamepad.rs#L1117-1120
defines gilrs_core::platform::native_ev_codes::AXIS_LEFTZ
as ABS_Z
https://gitlab.com/gilrs-project/gilrs/-/blob/7cd001dacfb188405e5e41520912a259367a4703/gilrs-core/src/platform/linux/gamepad.rs#L1012
defines ABS_Z
as 0x02
https://github.com/torvalds/linux/blob/9f4211bf7f811b653aa6acfb9aea38222436a458/include/uapi/linux/input-event-codes.h#L844
Also defines ABS_Z
as 0x02
https://www.kernel.org/doc/html/v6.3/input/event-codes.html?highlight=abs_z#ev-abs Says: "If the input device may be used freely in three dimensions, consider ABS_Z instead."
Thank you @geophree!
I can confirm button_axes.get(GamepadButton(gamepad, GamepadButtonType::RightTrigger2))
with button_axes: Res<Axis<GamepadButton>>
works for wired Xbox 360 controller in Bevy 0.13.2.
What went wrong
RightTrigger2
input is not logged when trying thecargo run --example gamepad_input
example on linux. Gampad verified to be working (all axes, triggers, buttons) via https://greggman.github.io/html5-gamepad-test/Bevy version
(just pulled
latest
)Relevant system information
System
cargo:
What you did
Ran
cargo run --example gamepad_input
, and tried pressing all the buttons and wiggling the sticks on the gamepad.Here are the first several lines of output when I run the example