-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
UI: Interaction
has limited usefulness, should have feature parity with Input
#7371
Comments
I like the direction of this design. What if we did an enum, but added |
I don't like the Further, only supporting methods has its benefits: UI interaction is even more complex that I don't see a benefit to a "middle ground". |
I use changed detection for that. |
That only works in simple scenarios. For example, I recently had a use case where I had to track other state/components too, and then that meant that change detection wouldn't let my query access the entities I needed. I could make multiple queries, use param sets, etc., to make it possible to use change detection, but at that point using Both of these "solutions" are just workarounds. The ergonomic solution would be to have |
Also, I think it is impossible to detect "just released" with change detection. What would you do? |
While working on #7240 I had similar thoughts and I think this issue describes my preferred solution pretty well. We do need more granular interaction support. Thought: Should enum Interaction {
JustPressed,
Released, // (same as JustReleased)
Pressed,
None
}
enum Hover {
JustEntered
JustExited
Hover
None
} |
Oh I like splitting |
I don't like splitting Hover, because systems that handle UI interaction should be aware of and have easy access to all the possible interaction states that a UI Node can be in. If a user wants to support UI interaction properly regardless of input device, they probably want access to it all. With my proposed solution, if users don't care about hover ... they can just not call Splitting it into a separate component "just because not everybody wants it" just adds friction for everyone who does. People now need to care about two separate components, and perform logic to check the values of both. That's worse UX imo. Also, I really prefer not using enums, because enums force a very specific state machine mental model (the value can only ever be exactly one of the variants in the set) and makes the actual practical use cases clunky to handle. Even the proposal above showcases how this is insufficient. What is the difference between Just like in my original post, consider being like I strongly urge us to consider moving UI interaction to a similar method-based API style. Further, this allows us to have a If the mouse/touch release event happens within the confines of the UI node, then We cannot provide such nice user-friendly APIs with enums. UI interaction state is more complex and does not map cleanly to enums. |
From my point of view, the current
I'd like to see something like With such The appearance aspect works great in html/css: each element may have one or more Bevy could provide something like // it could be just String/'static &str or some sort of ImmutableString
pub enum UiStateEnum {
Pressed,
Hovered,
Active,
Focused,
}
#[derive(Component)
pub struct UiState(HashSet<UiStateEnum>); Later user can write separate system that covers ui appearance in response to With I've been experimenting with such a approach for some time and it feels very comfortable and powerful in |
What problem does this solve or what need does it fill?
Currently
Interaction
only detects 3 conditions:Clicked
: while pressed using mouse/touchHovered
: while the mouse pointer is on topNone
: none of the aboveThis is very limiting. For comparison, consider the kinds of things you can detect using
Input<MouseButton>
:pressed
: the button is held down (likeInteraction::Clicked
)released
: the button is not pressedjust_pressed
: only true the first frame when the button got pressedjust_released
: only true the first frame when the button stopped being pressedNotably,
just_pressed
/just_released
allow detecting the moment when the mouse click starts or ends. Having such functionality available for UI too, would be very useful.Consider a button in some UI. In many scenarios, you probably want to trigger its action only once, not repeatedly every frame while the button is held down (as currently happens if using
Interaction::Clicked
). Further, having the choice between doing it when the button is just pressed vs. just released, can be very useful depending on the intended user experience. Doing it on release can allow the user to cancel / back out of accidentally pressing the wrong UI button, by moving the cursor out of it before releasing. Doing it on on press means instant action/response with no delay, important for buttons in many game UIs.What solution would you like?
Interaction
, instead of being anenum
, could be converted to an API that mirrors that ofInput
, offering thepressed
/just_pressed
/released
/just_released
methods, + additionally also hover detection using ahovered
method.Pressing should only register if the event happened within the UI element. Pressing the mouse button outside, and then dragging the cursor in, should not cause the
Interaction
to become pressed.just_released
should only trigger if the release event happens within the UI element. If the user presses the UI element, then moves the cursor out of it and releases it there, there should be nojust_released
. Instead, we could provide acanceled
method for detecting this situation.Touchscreens should behave consistent with this behavior.
This would allow users to write UI code using the same familiar API as for gameplay input. UI has its own additional needs (like hover detection), and this is why I am not proposing to try to reuse
Input
itself outright.What alternative(s) have you considered?
Extending the
enum
with more variants:This is a more straightforward extension of what already exists. Hovever, it suffers from poor usability. The equivalent of the current
Clicked
(detect the button being held down) would have to check for either JustPressed OR Pressed.Additional context
I am currently working around the limitations of
Interaction
by also accessingRes<Input<MouseButton>>
and trying to use both simultaneously, so that I can implement the desired behavior. I needInteraction
, so that I know if the specific UI element is being interacted with, and then I needInput<MouseButton>
forjust_pressed
/just_released
to figure out the missing information. This is very clunky and annoying, and does not support touch screens.The text was updated successfully, but these errors were encountered: