-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework Input action pressed state to support multiple controllers #84943
Conversation
Not really... At most uncommon.
Input singleton has a signal for that. |
I meant, having two controllers mapped to the same action, with one being disconnect with one button being pressed might be a be rare. Maybe if there's a connectivity issue though.
Ah damn, I didn't see that and was checking for signals in display servers. I'll see if I can fix that. |
How does this PR compare to #84685? When I tested that PR, multiple input devices interacted seamlessly between each other (exactly like I'd expect them to). |
I think you might not have tested the situations where two controllers (both connected) have the same event mapped to a given action. Releasing on one of the controller should release the action, even if the other controller still pressed the action. The solution in #84685 does not take the |
Fixed CI issues (and fixed the joypad disconnection behavior issue too) |
This breaks |
Thanks, I tested locally and it should be fixed now. |
I am not so sure about iterating an array of bools after every event. My bitwise approach was faster. Also I had a small optimization to avoid updating strength when it wouldn't have effect. Though I guess it's maybe not feasible with the new code 🤔 |
Yeah. I agree it's slower but this is really not a bottleneck at all, as the array will be always be super small anyway. Inputs management needs to be optimized when processed at the node level, but in the Input singleton, as they are not propagated to the tree, it's less of an issue. |
I noticed that when you have connected joypad, it sends a released event at the beginning. It's a pre-existing issue though. |
0d98e0a
to
5bc0e1f
Compare
Updated the PR with Kobewi's feedback. I reorganized the code a bit but it seems to be working correctly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally, I can confirm this keeps test_analog_and_digital_input_2.zip working as expected.
@groud Could you upload a testing project that specifically tests the issue this is supposed to fix? I have multiple controllers to test it, but am not sure of a practical test scenario.
With the test project you provided, just replace the axis in the bindings by a controller button. This is what happens in 4.2: Basically, the action is set as "unpressed" when releasing the button on the blue controller, while I still press the button on the black controller. This PR fixes that, and only releases the action when both controllers are released. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense given the explanation given here: #84943 (comment)
Thanks! |
I just tested this and now I'm even more confused than before. What I would expect given two joypads are mapped to the same action (let's call the action "joy_a") and both press the mapped input (let's say button A on two Xbox controller for example), then one of the joypads released the button and then the other ... func _process(delta):
if Input.is_action_just_pressed("joy_a"):
print("joy_a is just pressed")
if Input.is_action_just_released("joy_a"):
print("joy_a is just released") I would expect this to print:
So all of the joypad "presses" and "releases" I would expect to register and print. Godot 3.5.3:
Godot 4.2.1:
Godot 4.3 dev1:
I also tested all of this with a single Input (All Devices) mapping, and with two mappings (for both Device 0, Device 1), same result. To be clear, I would expected the result to be the same. I just wanted to be sure this is not correlated. It first glance it seems like Godot 3.5.3 and Godot 4.3. Dev1 behave the same. But they do not. If you press and hold A on joypad_0, then repeatedly quickly press A on the other joypad_1 (while still holding A on joypad__0), in Godot 3.5.3, the first "press" is from the joypad_0, the first "release" is from joypad_1, and then it's only joypad_1 printing "press" and "release": Godot 3.5.3:
Note: When finally releasing A on joypad_0, (which was held all while pressing A joypad_1 repeatedly), it won't print "released"! In Godot 4.2.1:
In contrast to Godot 3.5.3, joypad_0 will print "release" once it is finally released! But the first joypad_1 "pressed" is not printed. In Godot 4.3 Dev1:
Godot 4.3 Dev1 is totally different once again, not printing either "pressed" nor "released" of joypad_1, regardless how often you press A on joypad_1, while Button A of joypad_0 is held. To reiterate, what I would expect is all joypad presses and released to register and print. So in the above example of A on joypad_0 being held while A on joypad_1 is repeadedly pressed, I would expect this to print:
However none of the Godot versions I tested behaved as expected. |
@golddotasksquestions Please post this as a separate issue, not a comment on a PR merged 2 weeks ago (people are likely to miss it) |
Just to answer quickly, I am not sure this would be the expected behavior for everyone:
Since like some may not expect an action to be pressed again once it is already in the I think this thus deserves a dedicated issue or proposal. |
@groud If one of my players presses or releases any Input, as the dev, I want to know about it. |
Well, the events are received normally. This only affects action's pressed state. |
This implements the following changes:
_update_action_cache
function, only when an event is received.I tested the PR with a keyboard and two controllers connected to the same computer and it worked fine.
Disclaimer: the only thing it does not support right now is controllers correctly being unpressed automatically if they get disconnected. I think it's a rare situation, and it would be hard to fix as I didn't find a way to detect when a device was unplugged.This is now fixed.I did set the milestone to 4.3 as I think it's quite late for such a change for 4.2. I set both bug and enhancement tags as I am not sure which one it is.