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

Action Event Layers, multifocus for split screen #20091

Closed
wants to merge 5 commits into from

Conversation

Faless
Copy link
Collaborator

@Faless Faless commented Jul 10, 2018

This is something I briefly discussed with some devs at last GodotCon.
Closes #10755

TL;DR;

This PR adds adds Viewport-based multifocus support to GUI elements.
Additionally, it adds a new layer property in the Input Map editor to control this new focus behaviour.
Check out the demo: ActionLayer.zip

How does it work?

InputEvent now has a new layer property.
Each Viewport is assigned a new focus_layer property.
Focusing something inside that Viewport will only remove the focus from elements in viewports that have the same focus_layer.
When receiving input the Viewport (or ViewportContainer) will set the InputEvent layer property to the current focus_layer.
The InputMap._find_event (and thus all is_action,add_action, ...) will ignore actions with mismatching layers, causing UI inside each Viewport to only react to the appropriate input.

How do I use it?

Create a scene with multiple Viewports, eg:
hierarchy

Assign to the Viewport the desired focus_layer:
inspector

Consigure Input Map Layer property accordingly:
settings

@groud
Copy link
Member

groud commented Jul 11, 2018

I'm still not sure this is the best solution to solve the problem. But it seems we really need a way to handle several players for a single action.

Regarding the per-viewport focus, I don't think it is a good idea. It's not generic enough because you could have two focus points on the same screen (like in super smash bros I'd say or any other character selection menu)

@eon-s
Copy link
Contributor

eon-s commented Jul 17, 2018

Maybe making a bitmask like the rest of the layer systems? So a single viewport can handle many layers.

@reduz
Copy link
Member

reduz commented Jul 20, 2018

This PR is very close to what I had in mind. Let me explain you my idea, which is almost the same so we can agree on something.

I think the right solution is something along the lines of:

  1. Add a use_local_focus option to Viewport, so it does not get stolen by another viewport.
  2. Add an "input_layer" to events within the action. An enum (All layers,0-15) is probably better than a spinbox. All layers can map to -1.
  3. Add an "input_layer" for Viewports (Same, All layers, 0-15).
  4. Add an optional layer argument to InputEvent::is_action* functions (by default -1, which is all layers)
  5. Here is where it gets more difficult, add also an optional layer argument to Input.is_action* functions, (also by default -1). This will require some hacking to get to work right.

This would allow the following scenarios to work smoothly:

  • Have inputs going to different viewports, with different focus
  • Write multiplayer code that does not rely on creating the same action many times for each player

Why not bitmasks?

While bitmasks make more sense from the code side and are more flexible, they have the big downside that most game developers don't really understand how to set bitmasks manually. Making the API like:

if (Input.is_action_just_pressed("jump",1<<player)):

Will freak out a lot of users.

@Faless what do you think?

@groud
Copy link
Member

groud commented Jul 20, 2018

I'd say @reduz 's solution is a pretty clean way to solve both issues. I like it.

We may want to have a look to previous PR about adding multiplayer support to actions. (I think I remember a PR from Odino, but I cannot check now I am on my phone)

@groud
Copy link
Member

groud commented Jul 20, 2018

Nevermind, I cannot find it. It may simply have been discussed via IRC.

@Faless
Copy link
Collaborator Author

Faless commented Jul 20, 2018

@reduz , I agree with pretty much everything, I'll work on that.

@reduz
Copy link
Member

reduz commented Jul 20, 2018

@Faless In fact, I think it would make more sense to rename "layer" to just "player".

@reduz
Copy link
Member

reduz commented Aug 10, 2018

Had any time to think of a better solution to the one I proposed? Otherwise we can kick to 3.2 as we are too close to Alpha.

@Faless
Copy link
Collaborator Author

Faless commented Aug 11, 2018

Had any time to think of a better solution to the one I proposed? Otherwise we can kick to 3.2 as we are too close to Alpha.

I tried. Not hacking the player into InputEvents means either changing the InputMap API (which is not doable for 3.1) or doing a lot of hacking in the way the action maps are handled internally.
I tried the latter, but couldn't get a working version. I was then sucked up in the GSoC project and stopped working on it.

As much as I would love to see this feature in 3.1 will have to be pushed to 3.2

@Faless Faless modified the milestones: 3.1, 3.2 Aug 11, 2018
@akien-mga
Copy link
Member

Now would probably be a good time to revisit this PR and see if/how we want to merge it for 3.2 (or 4.0)

@Faless
Copy link
Collaborator Author

Faless commented Jun 22, 2019

Not going to happen, apparently there's not enough interest in adding this "complication".

@djpeach
Copy link

djpeach commented Aug 3, 2023

For anyone finding this in the future, support for this is coming (hopefully) in Sauermann's implementation (split into #78762 and #79480). It allows nested input layers/screens without losing focus, local splitscreen menu's, and really whatever the dev wants to do.

Demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add multiple UI focus groups
8 participants