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