Skip to content
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

Provide tools to "absorb" UI clicks and distinguish between UI element events and game events #5179

Closed
alice-i-cecile opened this issue Jul 2, 2022 · 4 comments
Labels
A-Input Player input via keyboard, mouse, gamepad, and more C-Feature A new feature, making something new possible

Comments

@alice-i-cecile
Copy link
Member

What problem does this solve or what need does it fill?

Clicks (and touches) on UI elements should generally not be sent through to the game.

For example, in a MOBA, clicking on the ability icons at the bottom of the screen should not cause your character to attempt to move to an obscured portion of the map.

While the FocusPolicy enum exists and functions correctly, it can only block click events for other UI elements (IIRC in the same tree), and so does not solve this problem.

What solution would you like?

#[derive(Default)
enum FocusPolicy {
  #[default]
  /// Blocks cursor events from overlapped UI and game elements
  Block,
  /// Blocks cursor events from overlapping game elements, but passes them down to overlapped UI elements
  BlockGameElements,
  /// Blocks cursor events from overlapping UI elements, but passes them down to overlapped game elements
  BlockUiElements,
  /// Passes all cursor events to overlapping game and UI elements
  Pass,
}

Actually implementing this likely involves:

  1. Unifying touch and mouse input to some degree.
  2. Splitting the event stream into UiCursor and GameCursor event streams, which are listened to in end-user systems.
  3. Dispatching raw cursor events into these two streams based on the current layout of the UI and the FocusPolicy of each element.

Workarounds

As a workaround, you can carefully define areas as "UI" or "game", and then read and split the event stream. This is quite painful on several levels though.

You could also absorb

Additional context

bevy_egui needs this too (see vladbat00/bevy_egui#47), and ideally the provided solution can be used for 3rd party UI crates seamlessly.

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Input Player input via keyboard, mouse, gamepad, and more labels Jul 2, 2022
@HackerFoo
Copy link
Contributor

How would you handle the situation where a button is pressed over a UI element, the cursor is moved away, and then the button is released? Or vice versa (e.g. drag and drop)?

Wouldn't each layer in the UI need to pass events (or not) to another stream to the layer beneath it?

My solution is to allow systems to negotiate with the input system (in this case, with a multitouch screen.)

  1. Touch contacts initially have no owner.
  2. A system can claim a contact using a unique ID (e.g. an Entity) This could be simply based on the region, or something more complex, like a ray trace.
  3. Claiming a contact causes a reset for that contact as well as any others sharing that ID, as if restarting the contact at that point. This is necessary to have a common frame of reference. Might not be necessary for single touch or a mouse, but it still might be useful to store the point at which the contact was claimed. Systems can also disown a contact, which also causes a reset.
  4. Systems can filter contacts that they have claimed, so irrelevant contacts can be ignored.

This is kind of similar to how an Ethernet switch works - when the destination of a packet is unknown, the switch sends the packet on all ports, until something replies, and then packets are only sent on the port where the reply was received.

I found this system flexible enough to handle both conventional flat UI tasks as well as complicated transitions between different spaces.

@Nilirad
Copy link
Contributor

Nilirad commented Jul 3, 2022

You could also absorb

The rest of the sentence have been absorbed.

@alice-i-cecile
Copy link
Member Author

@HackerFoo your insight here is much appreciated. Perhaps we should build out a more powerful cursor event system along the lines of what @colepoirier was investigating first or in concert with this work.

@mockersf
Copy link
Member

mockersf commented Jul 3, 2022

duplicate of #3570

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Input Player input via keyboard, mouse, gamepad, and more C-Feature A new feature, making something new possible
Projects
None yet
Development

No branches or pull requests

4 participants