Path: blob/main/crates/bevy_input/src/common_conditions.rs
6595 views
use crate::ButtonInput;1use bevy_ecs::system::Res;2use core::hash::Hash;34/// Stateful run condition that can be toggled via an input press using [`ButtonInput::just_pressed`].5///6/// ```no_run7/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, Update};8/// # use bevy_ecs::prelude::IntoScheduleConfigs;9/// # use bevy_input::{common_conditions::input_toggle_active, prelude::KeyCode};10///11/// fn main() {12/// App::new()13/// .add_plugins(DefaultPlugins)14/// .add_systems(Update, pause_menu.run_if(input_toggle_active(false, KeyCode::Escape)))15/// .run();16/// }17///18/// fn pause_menu() {19/// println!("in pause menu");20/// }21/// ```22///23/// If you want other systems to be able to access whether the toggled state is active,24/// you should use a custom resource or a state for that:25/// ```no_run26/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, Update};27/// # use bevy_ecs::prelude::{IntoScheduleConfigs, Res, ResMut, Resource};28/// # use bevy_input::{common_conditions::input_just_pressed, prelude::KeyCode};29///30/// #[derive(Resource, Default)]31/// struct Paused(bool);32///33/// fn main() {34/// App::new()35/// .add_plugins(DefaultPlugins)36/// .init_resource::<Paused>()37/// .add_systems(Update, toggle_pause_state.run_if(input_just_pressed(KeyCode::Escape)))38/// .add_systems(Update, pause_menu.run_if(|paused: Res<Paused>| paused.0))39/// .run();40/// }41///42/// fn toggle_pause_state(mut paused: ResMut<Paused>) {43/// paused.0 = !paused.0;44/// }45///46/// fn pause_menu() {47/// println!("in pause menu");48/// }49/// ```50pub fn input_toggle_active<T>(51default: bool,52input: T,53) -> impl FnMut(Res<ButtonInput<T>>) -> bool + Clone54where55T: Copy + Eq + Hash + Send + Sync + 'static,56{57let mut active = default;58move |inputs: Res<ButtonInput<T>>| {59active ^= inputs.just_pressed(input);60active61}62}6364/// Run condition that is active if [`ButtonInput::pressed`] is true for the given input.65pub fn input_pressed<T>(input: T) -> impl FnMut(Res<ButtonInput<T>>) -> bool + Clone66where67T: Copy + Eq + Hash + Send + Sync + 'static,68{69move |inputs: Res<ButtonInput<T>>| inputs.pressed(input)70}7172/// Run condition that is active if [`ButtonInput::just_pressed`] is true for the given input.73///74/// ```no_run75/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, Update};76/// # use bevy_ecs::prelude::IntoScheduleConfigs;77/// # use bevy_input::{common_conditions::input_just_pressed, prelude::KeyCode};78/// fn main() {79/// App::new()80/// .add_plugins(DefaultPlugins)81/// .add_systems(Update, jump.run_if(input_just_pressed(KeyCode::Space)))82/// .run();83/// }84///85/// # fn jump() {}86/// ```87pub fn input_just_pressed<T>(input: T) -> impl FnMut(Res<ButtonInput<T>>) -> bool + Clone88where89T: Copy + Eq + Hash + Send + Sync + 'static,90{91move |inputs: Res<ButtonInput<T>>| inputs.just_pressed(input)92}9394/// Run condition that is active if [`ButtonInput::just_released`] is true for the given input.95pub fn input_just_released<T>(input: T) -> impl FnMut(Res<ButtonInput<T>>) -> bool + Clone96where97T: Copy + Eq + Hash + Send + Sync + 'static,98{99move |inputs: Res<ButtonInput<T>>| inputs.just_released(input)100}101102#[cfg(test)]103mod tests {104use super::*;105use crate::prelude::KeyCode;106use bevy_ecs::schedule::{IntoScheduleConfigs, Schedule};107108fn test_system() {}109110// Ensure distributive_run_if compiles with the common conditions.111#[test]112fn distributive_run_if_compiles() {113Schedule::default().add_systems(114(test_system, test_system)115.distributive_run_if(input_toggle_active(false, KeyCode::Escape))116.distributive_run_if(input_pressed(KeyCode::Escape))117.distributive_run_if(input_just_pressed(KeyCode::Escape))118.distributive_run_if(input_just_released(KeyCode::Escape)),119);120}121}122123124