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

Input event still passed down to the game when I type inside the console. #2

Open
zsdominik opened this issue Dec 15, 2021 · 6 comments
Labels
bug Something isn't working

Comments

@zsdominik
Copy link

Hi. I was able to smack this bad boy into my game and it is working correctly. My problem is that if I have controls assigned to certain characters for example 'A', 'D' etc.. The game still registers this.

Is that possible to block the capturing of the input events to the game when the terminal is up?

@RichoDemus RichoDemus added the bug Something isn't working label Dec 17, 2021
@RichoDemus
Copy link
Owner

I don't actually now, if you could figure that out I can fix it, or you can open a PR yourself :)

@mwcz
Copy link

mwcz commented Jul 2, 2022

If anyone else comes across this, I worked around this in my game by handling input only if the console is closed, like this:

fn handle_input(
    mut events: EventReader<KeyboardInput>,
    console_open: Res<ConsoleOpen>,
) {
    if !console_open.open {
        for event in events.iter() {
            if let ElementState::Pressed = event.state {
                if let Some(KeyCode::T) = event.key_code {
                    // handle pressing T
                }
            }
        }
    }
}

I quickly checked to see if this method could also work with leafwing-input-manager, and my best guess at how to temporarily disable the input manager is release_all, though I haven't tested it.

@makspll
Copy link
Collaborator

makspll commented Aug 10, 2022

Okay I think a possible solution would be creating a system which users can opt-in for which "consumes" all keyboard events after the console_ui system runs. (I believe egui processes inputs on PreUpdate, so the console input still should work, and since it would run after console_ui it would be possible to change console state)

i.e.:

pub fn block_inputs_on_console_focus(
    mut events: ResMut<Events<KeyboardInput>>, 
    console_open: Res<ConsoleOpen>
){
   if console_open.open {
      events.drain().for_each(drop)
   }
}

I don't think we should make this a default though since removing all keyboard inputs downstream is very imposing,

@brandon-reinhart what do you think ?

@vabrador
Copy link

vabrador commented Aug 16, 2022

I quickly checked to see if this method could also work with leafwing-input-manager, and my best guess at how to temporarily disable the input manager is release_all, though I haven't tested it.

Can confirm that release_all() is a valid approach for preventing game input while the console is open, assuming your main game input is routed through leafwing_input_manager:

I have a plugin that adds the console plugin and custom commands, and clears input before CoreStage::Update:

pub struct ConsoleCommandsPlugin;

/// This stage runs at before Update, and clears out the leafwing ActionState to prevent character/game input while the console is open.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(StageLabel)]
struct ConsoleClearLeafwingInputStage;

impl Plugin for ConsoleCommandsPlugin {
    fn build(&self, app: &mut App) {
        app
            .add_plugin(bevy_console::ConsolePlugin)

            // Add a system that consumes keyboard input while the console is open.
            // It occurs before Update to ensure it happens before Leafwing input is consumed.
            .add_stage_before(CoreStage::Update, ConsoleClearLeafwingInputStage, SystemStage::parallel())
            .add_system_to_stage(ConsoleClearLeafwingInputStage, clear_leafwing_input)
            
            .add_console_command::<LogCommand, _, _>(log_command) // etc.
        ;
    }
}

fn clear_leafwing_input(
    mut query_actions: Query<&mut leafwing_input_manager::prelude::ActionState::<
        crate::main_game::input_leafwing::Action> // (this type would need to be your own game's Action type)
    >,
    console_open: Res<ConsoleOpen>
) {
    if console_open.open {
        for mut leafwing_action_state in query_actions.iter_mut() {
            leafwing_action_state.release_all();
        }
    }
}

Adding my two cents on input exclusivity, dedicated ad-hoc solutions (such as the release_all() strategy when using leafwing-input-manager) might be necessary for any project that grows large enough, but @makspll's suggestion to drain keyboard events as a non-default ConsoleConfiguration option seems like a great option for covering the needs of new projects.

@calteran
Copy link

calteran commented Jan 16, 2023

FWIW, leafwing-input-manager has an optional feature egui that provides this functionality. All you have to do is opt-in in Cargo.toml and leafwing will ignore input whenever an egui window (like bevy_console's) is open. Obviously that doesn't solve this issue for all input managers, but I'm commenting here for visibility.

Edit: I've just noted a regression where the feature flag no longer works to prevent this behavior. I'll update this comment if I discover a fix.

@Kromey
Copy link

Kromey commented Apr 14, 2023

You should be able to handle this in your own input handling by simply checking wants_keyboard_input, although I haven't yet tried this myself. IMO this shouldn't be something that bevy-console should be asked to handle for you, but (assuming this works) it would be good to call out in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants