use bevy::prelude::*; use bevy::window::{CursorGrabMode, PrimaryWindow, WindowResolution}; use bevy::input::{ButtonState, keyboard::KeyboardInput}; pub struct WindowPlugin; impl Plugin for WindowPlugin { fn build(&self, app: &mut App) { app.add_systems(PreStartup, setup_window); app.add_event::(); app.add_systems(PreUpdate, on_cursor_grab_toggled.run_if(on_event::)); } } #[derive(Event)] pub struct CursorGrabEvent(pub bool); fn setup_window( mut window: Query<&mut Window, With>, ) { let mut window = window.single_mut(); window.title = "Bevy FPS Game".to_string(); window.resolution = WindowResolution::new(1920.0, 1080.0); window.position = WindowPosition::Centered(MonitorSelection::Primary); } fn on_cursor_grab_toggled( mut window: Query<&mut Window, With>, mut events: EventReader, mut cursor_events: EventWriter, ) { let mut window = window.single_mut(); for _ in events.read() .filter(|event| event.key_code == KeyCode::Escape) .filter(|event| event.state == ButtonState::Pressed) { match window.cursor_options.grab_mode { CursorGrabMode::None => { window.cursor_options.visible = false; window.cursor_options.grab_mode = CursorGrabMode::Locked; cursor_events.send(CursorGrabEvent(true)); } CursorGrabMode::Locked => { window.cursor_options.visible = true; window.cursor_options.grab_mode = CursorGrabMode::None; cursor_events.send(CursorGrabEvent(false)); } _ => panic!("Invalid cursor grab mode"), } } }