Struct bevy::input::ButtonInput
pub struct ButtonInput<T>{ /* private fields */ }
Expand description
A “press-able” input of type T
.
§Usage
This type can be used as a resource to keep the current state of an input, by reacting to events from the input. For a given input value:
ButtonInput::pressed
will returntrue
between a press and a release event.ButtonInput::just_pressed
will returntrue
for one frame after a press event.ButtonInput::just_released
will returntrue
for one frame after a release event.
§Multiple systems
In case multiple systems are checking for ButtonInput::just_pressed
or ButtonInput::just_released
but only one should react, for example in the case of triggering
State
change, you should consider clearing the input state, either by:
- Using
ButtonInput::clear_just_pressed
orButtonInput::clear_just_released
instead. - Calling
ButtonInput::clear
orButtonInput::reset
immediately after the state change.
§Performance
For all operations, the following conventions are used:
- n is the number of stored inputs.
- m is the number of input arguments passed to the method.
- *-suffix denotes an amortized cost.
- ~-suffix denotes an expected cost.
See Rust’s std::collections doc on performance for more details on the conventions used here.
| ButtonInput
operations | Computational complexity |
|———————————–|————————————|
| ButtonInput::any_just_pressed
| O(m)~ |
| ButtonInput::any_just_released
| O(m)~ |
| ButtonInput::any_pressed
| O(m)~ |
| ButtonInput::get_just_pressed
| O(n) |
| ButtonInput::get_just_released
| O(n) |
| ButtonInput::get_pressed
| O(n) |
| ButtonInput::just_pressed
| O(1)~ |
| ButtonInput::just_released
| O(1)~ |
| ButtonInput::pressed
| O(1)~ |
| ButtonInput::press
| O(1)* |
| * |
| ButtonInput::release
| O(1)ButtonInput::release_all
| O(n)* |
| |
| ButtonInput::clear_just_pressed
| O(1)ButtonInput::clear_just_released
| *O*(1)~ |
| ButtonInput::reset_all
| O(n) |
| ButtonInput::clear
| O(n) |
§Window focus
ButtonInput<KeyCode>
is tied to window focus. For example, if the user holds a button
while the window loses focus, ButtonInput::just_released
will be triggered. Similarly if the window
regains focus, ButtonInput::just_pressed
will be triggered. Currently this happens even if the
focus switches from one Bevy window to another (for example because a new window was just spawned).
ButtonInput<GamepadButton>
is independent of window focus.
§Examples
Reading and checking against the current set of pressed buttons:
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(
Update,
print_gamepad.run_if(resource_changed::<ButtonInput<GamepadButton>>),
)
.add_systems(
Update,
print_mouse.run_if(resource_changed::<ButtonInput<MouseButton>>),
)
.add_systems(
Update,
print_keyboard.run_if(resource_changed::<ButtonInput<KeyCode>>),
)
.run();
}
fn print_gamepad(gamepad: Res<ButtonInput<GamepadButton>>) {
println!("Gamepad: {:?}", gamepad.get_pressed().collect::<Vec<_>>());
}
fn print_mouse(mouse: Res<ButtonInput<MouseButton>>) {
println!("Mouse: {:?}", mouse.get_pressed().collect::<Vec<_>>());
}
fn print_keyboard(keyboard: Res<ButtonInput<KeyCode>>) {
if keyboard.any_pressed([KeyCode::ControlLeft, KeyCode::ControlRight])
&& keyboard.any_pressed([KeyCode::AltLeft, KeyCode::AltRight])
&& keyboard.any_pressed([KeyCode::ShiftLeft, KeyCode::ShiftRight])
&& keyboard.any_pressed([KeyCode::SuperLeft, KeyCode::SuperRight])
&& keyboard.pressed(KeyCode::KeyL)
{
println!("On Windows this opens LinkedIn.");
} else {
println!("keyboard: {:?}", keyboard.get_pressed().collect::<Vec<_>>());
}
}
Accepting input from multiple devices:
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(
Update,
something_used.run_if(
input_just_pressed(KeyCode::KeyE)
.or_else(input_just_pressed(GamepadButton::new(
Gamepad::new(0),
GamepadButtonType::West,
))),
),
)
.run();
}
fn something_used() {
println!("Generic use-ish button pressed.");
}
§Note
When adding this resource for a new input type, you should:
- Call the
ButtonInput::press
method for each press event. - Call the
ButtonInput::release
method for each release event. - Call the
ButtonInput::clear
method at each frame start, before processing events.
Note: Calling clear
from a ResMut
will trigger change detection.
It may be preferable to use DetectChangesMut::bypass_change_detection
to avoid causing the resource to always be marked as changed.
Implementations§
§impl<T> ButtonInput<T>
impl<T> ButtonInput<T>
pub fn press(&mut self, input: T)
pub fn press(&mut self, input: T)
Registers a press for the given input
.
pub fn pressed(&self, input: T) -> bool
pub fn pressed(&self, input: T) -> bool
Returns true
if the input
has been pressed.
Examples found in repository?
More examples
13 14 15 16 17 18 19 20 21 22 23 24
fn keyboard_input_system(keyboard_input: Res<ButtonInput<KeyCode>>) {
if keyboard_input.pressed(KeyCode::KeyA) {
info!("'A' currently pressed");
}
if keyboard_input.just_pressed(KeyCode::KeyA) {
info!("'A' just pressed");
}
if keyboard_input.just_released(KeyCode::KeyA) {
info!("'A' just released");
}
}
96 97 98 99 100 101 102 103 104 105 106 107 108 109
fn trigger_hooks(
mut commands: Commands,
keys: Res<ButtonInput<KeyCode>>,
index: Res<MyComponentIndex>,
) {
for (key, entity) in index.iter() {
if !keys.pressed(*key) {
commands.entity(*entity).remove::<MyComponent>();
}
}
for key in keys.get_just_pressed() {
commands.spawn(MyComponent(*key));
}
}
13 14 15 16 17 18 19 20 21 22 23 24 25
fn mouse_click_system(mouse_button_input: Res<ButtonInput<MouseButton>>) {
if mouse_button_input.pressed(MouseButton::Left) {
info!("left mouse currently pressed");
}
if mouse_button_input.just_pressed(MouseButton::Left) {
info!("left mouse just pressed");
}
if mouse_button_input.just_released(MouseButton::Left) {
info!("left mouse just released");
}
}
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
fn movement(
input: Res<ButtonInput<KeyCode>>,
time: Res<Time>,
mut query: Query<&mut Transform, With<Movable>>,
) {
for mut transform in &mut query {
let mut direction = Vec3::ZERO;
if input.pressed(KeyCode::ArrowUp) {
direction.y += 1.0;
}
if input.pressed(KeyCode::ArrowDown) {
direction.y -= 1.0;
}
if input.pressed(KeyCode::ArrowLeft) {
direction.x -= 1.0;
}
if input.pressed(KeyCode::ArrowRight) {
direction.x += 1.0;
}
transform.translation += time.delta_seconds() * 2.0 * direction;
}
}
- examples/audio/spatial_audio_3d.rs
- examples/audio/spatial_audio_2d.rs
- examples/ecs/state.rs
- examples/3d/spotlight.rs
- examples/games/breakout.rs
- examples/3d/generate_custom_mesh.rs
- examples/3d/irradiance_volumes.rs
- examples/stress_tests/bevymark.rs
- examples/gizmos/light_gizmos.rs
- examples/2d/rotation.rs
- examples/3d/tonemapping.rs
- examples/games/alien_cake_addict.rs
- examples/gizmos/2d_gizmos.rs
- examples/3d/blend_modes.rs
- examples/gizmos/3d_gizmos.rs
- examples/3d/bloom_3d.rs
- examples/2d/bloom_2d.rs
- examples/tools/scene_viewer/../../helpers/camera_controller.rs
- examples/3d/fog.rs
- examples/3d/transmission.rs
pub fn any_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool
pub fn any_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool
Returns true
if any item in inputs
has been pressed.
Examples found in repository?
More examples
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
fn update_system(
mut camera: Query<(&mut FogSettings, &mut Transform)>,
mut text: Query<&mut Text>,
time: Res<Time>,
keycode: Res<ButtonInput<KeyCode>>,
) {
let now = time.elapsed_seconds();
let delta = time.delta_seconds();
let (mut fog, mut transform) = camera.single_mut();
let mut text = text.single_mut();
// Orbit camera around pyramid
let orbit_scale = 8.0 + (now / 10.0).sin() * 7.0;
*transform = Transform::from_xyz(
(now / 5.0).cos() * orbit_scale,
12.0 - orbit_scale / 2.0,
(now / 5.0).sin() * orbit_scale,
)
.looking_at(Vec3::ZERO, Vec3::Y);
// Fog Information
text.sections[0].value = format!("Fog Falloff: {:?}\nFog Color: {:?}", fog.falloff, fog.color);
// Fog Falloff Mode Switching
text.sections[0]
.value
.push_str("\n\n1 / 2 / 3 - Fog Falloff Mode");
if keycode.pressed(KeyCode::Digit1) {
if let FogFalloff::Linear { .. } = fog.falloff {
// No change
} else {
fog.falloff = FogFalloff::Linear {
start: 5.0,
end: 20.0,
};
};
}
if keycode.pressed(KeyCode::Digit2) {
if let FogFalloff::Exponential { .. } = fog.falloff {
// No change
} else if let FogFalloff::ExponentialSquared { density } = fog.falloff {
fog.falloff = FogFalloff::Exponential { density };
} else {
fog.falloff = FogFalloff::Exponential { density: 0.07 };
};
}
if keycode.pressed(KeyCode::Digit3) {
if let FogFalloff::Exponential { density } = fog.falloff {
fog.falloff = FogFalloff::ExponentialSquared { density };
} else if let FogFalloff::ExponentialSquared { .. } = fog.falloff {
// No change
} else {
fog.falloff = FogFalloff::Exponential { density: 0.07 };
};
}
// Linear Fog Controls
if let FogFalloff::Linear {
ref mut start,
ref mut end,
} = &mut fog.falloff
{
text.sections[0]
.value
.push_str("\nA / S - Move Start Distance\nZ / X - Move End Distance");
if keycode.pressed(KeyCode::KeyA) {
*start -= delta * 3.0;
}
if keycode.pressed(KeyCode::KeyS) {
*start += delta * 3.0;
}
if keycode.pressed(KeyCode::KeyZ) {
*end -= delta * 3.0;
}
if keycode.pressed(KeyCode::KeyX) {
*end += delta * 3.0;
}
}
// Exponential Fog Controls
if let FogFalloff::Exponential { ref mut density } = &mut fog.falloff {
text.sections[0].value.push_str("\nA / S - Change Density");
if keycode.pressed(KeyCode::KeyA) {
*density -= delta * 0.5 * *density;
if *density < 0.0 {
*density = 0.0;
}
}
if keycode.pressed(KeyCode::KeyS) {
*density += delta * 0.5 * *density;
}
}
// ExponentialSquared Fog Controls
if let FogFalloff::ExponentialSquared { ref mut density } = &mut fog.falloff {
text.sections[0].value.push_str("\nA / S - Change Density");
if keycode.pressed(KeyCode::KeyA) {
*density -= delta * 0.5 * *density;
if *density < 0.0 {
*density = 0.0;
}
}
if keycode.pressed(KeyCode::KeyS) {
*density += delta * 0.5 * *density;
}
}
// RGBA Controls
text.sections[0]
.value
.push_str("\n\n- / = - Red\n[ / ] - Green\n; / ' - Blue\n. / ? - Alpha");
// We're performing various operations in the sRGB color space,
// so we convert the fog color to sRGB here, then modify it,
// and finally when we're done we can convert it back and set it.
let mut fog_color = Srgba::from(fog.color);
if keycode.pressed(KeyCode::Minus) {
fog_color.red = (fog_color.red - 0.1 * delta).max(0.0);
}
if keycode.any_pressed([KeyCode::Equal, KeyCode::NumpadEqual]) {
fog_color.red = (fog_color.red + 0.1 * delta).min(1.0);
}
if keycode.pressed(KeyCode::BracketLeft) {
fog_color.green = (fog_color.green - 0.1 * delta).max(0.0);
}
if keycode.pressed(KeyCode::BracketRight) {
fog_color.green = (fog_color.green + 0.1 * delta).min(1.0);
}
if keycode.pressed(KeyCode::Semicolon) {
fog_color.blue = (fog_color.blue - 0.1 * delta).max(0.0);
}
if keycode.pressed(KeyCode::Quote) {
fog_color.blue = (fog_color.blue + 0.1 * delta).min(1.0);
}
if keycode.pressed(KeyCode::Period) {
fog_color.alpha = (fog_color.alpha - 0.1 * delta).max(0.0);
}
if keycode.pressed(KeyCode::Slash) {
fog_color.alpha = (fog_color.alpha + 0.1 * delta).min(1.0);
}
fog.color = Color::from(fog_color);
}
pub fn all_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool
pub fn all_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool
Returns true
if all items in inputs
have been pressed.
pub fn release(&mut self, input: T)
pub fn release(&mut self, input: T)
Registers a release for the given input
.
pub fn release_all(&mut self)
pub fn release_all(&mut self)
Registers a release for all currently pressed inputs.
pub fn just_pressed(&self, input: T) -> bool
pub fn just_pressed(&self, input: T) -> bool
Returns true
if the input
has been pressed during the current frame.
Note: This function does not imply information regarding the current state of ButtonInput::pressed
or ButtonInput::just_released
.
Examples found in repository?
More examples
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
fn pause(
keyboard_input: Res<ButtonInput<KeyCode>>,
music_controller: Query<&AudioSink, With<MyMusic>>,
) {
if keyboard_input.just_pressed(KeyCode::Space) {
if let Ok(sink) = music_controller.get_single() {
sink.toggle();
}
}
}
fn volume(
keyboard_input: Res<ButtonInput<KeyCode>>,
music_controller: Query<&AudioSink, With<MyMusic>>,
) {
if let Ok(sink) = music_controller.get_single() {
if keyboard_input.just_pressed(KeyCode::Equal) {
sink.set_volume(sink.volume() + 0.1);
} else if keyboard_input.just_pressed(KeyCode::Minus) {
sink.set_volume(sink.volume() - 0.1);
}
}
}
- examples/input/keyboard_modifiers.rs
- examples/input/keyboard_input.rs
- examples/dev_tools/fps_overlay.rs
- examples/stress_tests/many_gizmos.rs
- examples/window/scale_factor_override.rs
- examples/ui/ui.rs
- examples/input/mouse_input.rs
- examples/window/window_settings.rs
- examples/ecs/run_conditions.rs
- examples/2d/bounding_2d.rs
- examples/window/screenshot.rs
- examples/3d/atmospheric_fog.rs
- examples/window/low_power.rs
- examples/audio/spatial_audio_2d.rs
- examples/audio/pitch.rs
- examples/input/text_input.rs
- examples/input/mouse_grab.rs
- examples/ui/ui_scaling.rs
- examples/audio/spatial_audio_3d.rs
- examples/ui/overflow_debug.rs
- examples/window/window_resizing.rs
- examples/tools/gamepad_viewer.rs
- examples/games/loading_screen.rs
- examples/3d/tonemapping.rs
- examples/3d/shadow_caster_receiver.rs
- examples/tools/scene_viewer/scene_viewer_plugin.rs
- examples/3d/shadow_biases.rs
- examples/games/stepping.rs
- examples/3d/irradiance_volumes.rs
- examples/shader/shader_prepass.rs
- examples/3d/generate_custom_mesh.rs
- examples/3d/parallax_mapping.rs
- examples/input/gamepad_input.rs
- examples/2d/wireframe_2d.rs
- examples/3d/motion_blur.rs
- examples/3d/wireframe.rs
- examples/transforms/align.rs
- examples/3d/lighting.rs
- examples/tools/scene_viewer/animation_plugin.rs
- examples/3d/reflection_probes.rs
- examples/gizmos/light_gizmos.rs
- examples/stress_tests/many_foxes.rs
- examples/gizmos/2d_gizmos.rs
- examples/3d/anti_aliasing.rs
- examples/input/gamepad_rumble.rs
- examples/3d/blend_modes.rs
- examples/3d/ssao.rs
- examples/3d/deferred_rendering.rs
- examples/gizmos/3d_gizmos.rs
- examples/animation/animated_fox.rs
- examples/3d/bloom_3d.rs
- examples/2d/bloom_2d.rs
- examples/tools/scene_viewer/../../helpers/camera_controller.rs
- examples/3d/transmission.rs
pub fn any_just_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool
pub fn any_just_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool
Returns true
if any item in inputs
has been pressed during the current frame.
pub fn clear_just_pressed(&mut self, input: T) -> bool
pub fn clear_just_pressed(&mut self, input: T) -> bool
Clears the just_pressed
state of the input
and returns true
if the input
has just been pressed.
Future calls to ButtonInput::just_pressed
for the given input will return false until a new press event occurs.
pub fn just_released(&self, input: T) -> bool
pub fn just_released(&self, input: T) -> bool
Returns true
if the input
has been released during the current frame.
Note: This function does not imply information regarding the current state of ButtonInput::pressed
or ButtonInput::just_pressed
.
Examples found in repository?
13 14 15 16 17 18 19 20 21 22 23 24
fn keyboard_input_system(keyboard_input: Res<ButtonInput<KeyCode>>) {
if keyboard_input.pressed(KeyCode::KeyA) {
info!("'A' currently pressed");
}
if keyboard_input.just_pressed(KeyCode::KeyA) {
info!("'A' just pressed");
}
if keyboard_input.just_released(KeyCode::KeyA) {
info!("'A' just released");
}
}
More examples
13 14 15 16 17 18 19 20 21 22 23 24 25
fn mouse_click_system(mouse_button_input: Res<ButtonInput<MouseButton>>) {
if mouse_button_input.pressed(MouseButton::Left) {
info!("left mouse currently pressed");
}
if mouse_button_input.just_pressed(MouseButton::Left) {
info!("left mouse just pressed");
}
if mouse_button_input.just_released(MouseButton::Left) {
info!("left mouse just released");
}
}
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
fn update_buttons(
gamepads: Res<Gamepads>,
button_inputs: Res<ButtonInput<GamepadButton>>,
materials: Res<ButtonMaterials>,
mut query: Query<(&mut Handle<ColorMaterial>, &ReactTo)>,
) {
for gamepad in gamepads.iter() {
for (mut handle, react_to) in query.iter_mut() {
if button_inputs.just_pressed(GamepadButton::new(gamepad, **react_to)) {
*handle = materials.active.clone();
}
if button_inputs.just_released(GamepadButton::new(gamepad, **react_to)) {
*handle = materials.normal.clone();
}
}
}
}
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn gamepad_system(
gamepads: Res<Gamepads>,
button_inputs: Res<ButtonInput<GamepadButton>>,
button_axes: Res<Axis<GamepadButton>>,
axes: Res<Axis<GamepadAxis>>,
) {
for gamepad in gamepads.iter() {
if button_inputs.just_pressed(GamepadButton::new(gamepad, GamepadButtonType::South)) {
info!("{:?} just pressed South", gamepad);
} else if button_inputs.just_released(GamepadButton::new(gamepad, GamepadButtonType::South))
{
info!("{:?} just released South", gamepad);
}
let right_trigger = button_axes
.get(GamepadButton::new(
gamepad,
GamepadButtonType::RightTrigger2,
))
.unwrap();
if right_trigger.abs() > 0.01 {
info!("{:?} RightTrigger2 value is {}", gamepad, right_trigger);
}
let left_stick_x = axes
.get(GamepadAxis::new(gamepad, GamepadAxisType::LeftStickX))
.unwrap();
if left_stick_x.abs() > 0.01 {
info!("{:?} LeftStickX value is {}", gamepad, left_stick_x);
}
}
}
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
fn mouse_handler(
mut commands: Commands,
args: Res<Args>,
time: Res<Time>,
mouse_button_input: Res<ButtonInput<MouseButton>>,
windows: Query<&Window>,
bird_resources: ResMut<BirdResources>,
mut counter: ResMut<BevyCounter>,
mut rng: Local<Option<ChaCha8Rng>>,
mut wave: Local<usize>,
) {
if rng.is_none() {
// We're seeding the PRNG here to make this example deterministic for testing purposes.
// This isn't strictly required in practical use unless you need your app to be deterministic.
*rng = Some(ChaCha8Rng::seed_from_u64(42));
}
let rng = rng.as_mut().unwrap();
let window = windows.single();
if mouse_button_input.just_released(MouseButton::Left) {
counter.color = Color::linear_rgb(rng.gen(), rng.gen(), rng.gen());
}
if mouse_button_input.pressed(MouseButton::Left) {
let spawn_count = (BIRDS_PER_SECOND as f64 * time.delta_seconds_f64()) as usize;
spawn_birds(
&mut commands,
args.into_inner(),
&window.resolution,
&mut counter,
spawn_count,
bird_resources.into_inner(),
None,
*wave,
);
*wave += 1;
}
}
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
fn run_camera_controller(
time: Res<Time>,
mut windows: Query<&mut Window>,
mut mouse_events: EventReader<MouseMotion>,
mut scroll_events: EventReader<MouseWheel>,
mouse_button_input: Res<ButtonInput<MouseButton>>,
key_input: Res<ButtonInput<KeyCode>>,
mut toggle_cursor_grab: Local<bool>,
mut mouse_cursor_grab: Local<bool>,
mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
) {
let dt = time.delta_seconds();
if let Ok((mut transform, mut controller)) = query.get_single_mut() {
if !controller.initialized {
let (yaw, pitch, _roll) = transform.rotation.to_euler(EulerRot::YXZ);
controller.yaw = yaw;
controller.pitch = pitch;
controller.initialized = true;
info!("{}", *controller);
}
if !controller.enabled {
mouse_events.clear();
return;
}
let mut scroll = 0.0;
for scroll_event in scroll_events.read() {
let amount = match scroll_event.unit {
MouseScrollUnit::Line => scroll_event.y,
MouseScrollUnit::Pixel => scroll_event.y / 16.0,
};
scroll += amount;
}
controller.walk_speed += scroll * controller.scroll_factor * controller.walk_speed;
controller.run_speed = controller.walk_speed * 3.0;
// Handle key input
let mut axis_input = Vec3::ZERO;
if key_input.pressed(controller.key_forward) {
axis_input.z += 1.0;
}
if key_input.pressed(controller.key_back) {
axis_input.z -= 1.0;
}
if key_input.pressed(controller.key_right) {
axis_input.x += 1.0;
}
if key_input.pressed(controller.key_left) {
axis_input.x -= 1.0;
}
if key_input.pressed(controller.key_up) {
axis_input.y += 1.0;
}
if key_input.pressed(controller.key_down) {
axis_input.y -= 1.0;
}
let mut cursor_grab_change = false;
if key_input.just_pressed(controller.keyboard_key_toggle_cursor_grab) {
*toggle_cursor_grab = !*toggle_cursor_grab;
cursor_grab_change = true;
}
if mouse_button_input.just_pressed(controller.mouse_key_cursor_grab) {
*mouse_cursor_grab = true;
cursor_grab_change = true;
}
if mouse_button_input.just_released(controller.mouse_key_cursor_grab) {
*mouse_cursor_grab = false;
cursor_grab_change = true;
}
let cursor_grab = *mouse_cursor_grab || *toggle_cursor_grab;
// Apply movement update
if axis_input != Vec3::ZERO {
let max_speed = if key_input.pressed(controller.key_run) {
controller.run_speed
} else {
controller.walk_speed
};
controller.velocity = axis_input.normalize() * max_speed;
} else {
let friction = controller.friction.clamp(0.0, 1.0);
controller.velocity *= 1.0 - friction;
if controller.velocity.length_squared() < 1e-6 {
controller.velocity = Vec3::ZERO;
}
}
let forward = *transform.forward();
let right = *transform.right();
transform.translation += controller.velocity.x * dt * right
+ controller.velocity.y * dt * Vec3::Y
+ controller.velocity.z * dt * forward;
// Handle cursor grab
if cursor_grab_change {
if cursor_grab {
for mut window in &mut windows {
if !window.focused {
continue;
}
window.cursor.grab_mode = CursorGrabMode::Locked;
window.cursor.visible = false;
}
} else {
for mut window in &mut windows {
window.cursor.grab_mode = CursorGrabMode::None;
window.cursor.visible = true;
}
}
}
// Handle mouse input
let mut mouse_delta = Vec2::ZERO;
if cursor_grab {
for mouse_event in mouse_events.read() {
mouse_delta += mouse_event.delta;
}
} else {
mouse_events.clear();
}
if mouse_delta != Vec2::ZERO {
// Apply look update
controller.pitch = (controller.pitch
- mouse_delta.y * RADIANS_PER_DOT * controller.sensitivity)
.clamp(-PI / 2., PI / 2.);
controller.yaw -= mouse_delta.x * RADIANS_PER_DOT * controller.sensitivity;
transform.rotation =
Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
}
}
}
pub fn any_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool
pub fn any_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool
Returns true
if any item in inputs
has just been released.
pub fn clear_just_released(&mut self, input: T) -> bool
pub fn clear_just_released(&mut self, input: T) -> bool
Clears the just_released
state of the input
and returns true
if the input
has just been released.
Future calls to ButtonInput::just_released
for the given input will return false until a new release event occurs.
pub fn reset(&mut self, input: T)
pub fn reset(&mut self, input: T)
Clears the pressed
, just_pressed
and just_released
data of the input
.
pub fn reset_all(&mut self)
pub fn reset_all(&mut self)
Clears the pressed
, just_pressed
, and just_released
data for every input.
See also ButtonInput::clear
for simulating elapsed time steps.
pub fn clear(&mut self)
pub fn clear(&mut self)
Clears the just pressed
and just released
data for every input.
See also ButtonInput::reset_all
for a full reset.
pub fn get_pressed(&self) -> impl ExactSizeIterator
pub fn get_pressed(&self) -> impl ExactSizeIterator
An iterator visiting every pressed input in arbitrary order.
pub fn get_just_pressed(&self) -> impl ExactSizeIterator
pub fn get_just_pressed(&self) -> impl ExactSizeIterator
An iterator visiting every just pressed input in arbitrary order.
Note: Returned elements do not imply information regarding the current state of ButtonInput::pressed
or ButtonInput::just_released
.
Examples found in repository?
96 97 98 99 100 101 102 103 104 105 106 107 108 109
fn trigger_hooks(
mut commands: Commands,
keys: Res<ButtonInput<KeyCode>>,
index: Res<MyComponentIndex>,
) {
for (key, entity) in index.iter() {
if !keys.pressed(*key) {
commands.entity(*entity).remove::<MyComponent>();
}
}
for key in keys.get_just_pressed() {
commands.spawn(MyComponent(*key));
}
}
pub fn get_just_released(&self) -> impl ExactSizeIterator
pub fn get_just_released(&self) -> impl ExactSizeIterator
An iterator visiting every just released input in arbitrary order.
Note: Returned elements do not imply information regarding the current state of ButtonInput::pressed
or ButtonInput::just_pressed
.
Trait Implementations§
§impl<T> Clone for ButtonInput<T>
impl<T> Clone for ButtonInput<T>
§fn clone(&self) -> ButtonInput<T>
fn clone(&self) -> ButtonInput<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more§impl<T> Debug for ButtonInput<T>
impl<T> Debug for ButtonInput<T>
§impl<T> Default for ButtonInput<T>
impl<T> Default for ButtonInput<T>
§fn default() -> ButtonInput<T>
fn default() -> ButtonInput<T>
§impl<T> FromReflect for ButtonInput<T>
impl<T> FromReflect for ButtonInput<T>
§fn from_reflect(reflect: &(dyn Reflect + 'static)) -> Option<ButtonInput<T>>
fn from_reflect(reflect: &(dyn Reflect + 'static)) -> Option<ButtonInput<T>>
Self
from a reflected value.§fn take_from_reflect(
reflect: Box<dyn Reflect>
) -> Result<Self, Box<dyn Reflect>>
fn take_from_reflect( reflect: Box<dyn Reflect> ) -> Result<Self, Box<dyn Reflect>>
Self
using,
constructing the value using from_reflect
if that fails. Read more§impl<T> GetTypeRegistration for ButtonInput<T>
impl<T> GetTypeRegistration for ButtonInput<T>
§fn get_type_registration() -> TypeRegistration
fn get_type_registration() -> TypeRegistration
TypeRegistration
for this type.§fn register_type_dependencies(registry: &mut TypeRegistry)
fn register_type_dependencies(registry: &mut TypeRegistry)
§impl<T> Reflect for ButtonInput<T>
impl<T> Reflect for ButtonInput<T>
§fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
§fn into_any(self: Box<ButtonInput<T>>) -> Box<dyn Any>
fn into_any(self: Box<ButtonInput<T>>) -> Box<dyn Any>
Box<dyn Any>
.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut dyn Any
.§fn into_reflect(self: Box<ButtonInput<T>>) -> Box<dyn Reflect>
fn into_reflect(self: Box<ButtonInput<T>>) -> Box<dyn Reflect>
§fn as_reflect(&self) -> &(dyn Reflect + 'static)
fn as_reflect(&self) -> &(dyn Reflect + 'static)
§fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
§fn clone_value(&self) -> Box<dyn Reflect>
fn clone_value(&self) -> Box<dyn Reflect>
Reflect
trait object. Read more§fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>
§fn apply(&mut self, value: &(dyn Reflect + 'static))
fn apply(&mut self, value: &(dyn Reflect + 'static))
§fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
§fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
§fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
§fn reflect_owned(self: Box<ButtonInput<T>>) -> ReflectOwned
fn reflect_owned(self: Box<ButtonInput<T>>) -> ReflectOwned
§fn reflect_partial_eq(&self, value: &(dyn Reflect + 'static)) -> Option<bool>
fn reflect_partial_eq(&self, value: &(dyn Reflect + 'static)) -> Option<bool>
§fn reflect_hash(&self) -> Option<u64>
fn reflect_hash(&self) -> Option<u64>
§fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
§fn serializable(&self) -> Option<Serializable<'_>>
fn serializable(&self) -> Option<Serializable<'_>>
§fn is_dynamic(&self) -> bool
fn is_dynamic(&self) -> bool
§impl<T> Struct for ButtonInput<T>
impl<T> Struct for ButtonInput<T>
§fn field(&self, name: &str) -> Option<&(dyn Reflect + 'static)>
fn field(&self, name: &str) -> Option<&(dyn Reflect + 'static)>
name
as a &dyn Reflect
.§fn field_mut(&mut self, name: &str) -> Option<&mut (dyn Reflect + 'static)>
fn field_mut(&mut self, name: &str) -> Option<&mut (dyn Reflect + 'static)>
name
as a
&mut dyn Reflect
.§fn field_at(&self, index: usize) -> Option<&(dyn Reflect + 'static)>
fn field_at(&self, index: usize) -> Option<&(dyn Reflect + 'static)>
index
as a
&dyn Reflect
.§fn field_at_mut(&mut self, index: usize) -> Option<&mut (dyn Reflect + 'static)>
fn field_at_mut(&mut self, index: usize) -> Option<&mut (dyn Reflect + 'static)>
index
as a &mut dyn Reflect
.§fn iter_fields(&self) -> FieldIter<'_> ⓘ
fn iter_fields(&self) -> FieldIter<'_> ⓘ
§fn clone_dynamic(&self) -> DynamicStruct
fn clone_dynamic(&self) -> DynamicStruct
DynamicStruct
.§impl<T> TypePath for ButtonInput<T>
impl<T> TypePath for ButtonInput<T>
§fn short_type_path() -> &'static str
fn short_type_path() -> &'static str
§fn type_ident() -> Option<&'static str>
fn type_ident() -> Option<&'static str>
§fn crate_name() -> Option<&'static str>
fn crate_name() -> Option<&'static str>
§impl<T> Typed for ButtonInput<T>
impl<T> Typed for ButtonInput<T>
impl<T> Resource for ButtonInput<T>
Auto Trait Implementations§
impl<T> Freeze for ButtonInput<T>
impl<T> RefUnwindSafe for ButtonInput<T>where
T: RefUnwindSafe,
impl<T> Send for ButtonInput<T>
impl<T> Sync for ButtonInput<T>
impl<T> Unpin for ButtonInput<T>where
T: Unpin,
impl<T> UnwindSafe for ButtonInput<T>where
T: UnwindSafe,
Blanket Implementations§
§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> DynamicTypePath for Twhere
T: TypePath,
impl<T> DynamicTypePath for Twhere
T: TypePath,
§fn reflect_type_path(&self) -> &str
fn reflect_type_path(&self) -> &str
TypePath::type_path
.§fn reflect_short_type_path(&self) -> &str
fn reflect_short_type_path(&self) -> &str
§fn reflect_type_ident(&self) -> Option<&str>
fn reflect_type_ident(&self) -> Option<&str>
TypePath::type_ident
.§fn reflect_crate_name(&self) -> Option<&str>
fn reflect_crate_name(&self) -> Option<&str>
TypePath::crate_name
.§fn reflect_module_path(&self) -> Option<&str>
fn reflect_module_path(&self) -> Option<&str>
§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Self
using data from the given World
.§impl<T> GetPath for T
impl<T> GetPath for T
§fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>
) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p> ) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>>
path
. Read more§fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p> ) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>
path
. Read more§fn path<'p, T>(
&self,
path: impl ReflectPath<'p>
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
path
. Read more§fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
path
. Read more§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
§impl<T> NoneValue for Twhere
T: Default,
impl<T> NoneValue for Twhere
T: Default,
type NoneType = T
§fn null_value() -> T
fn null_value() -> T
§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian()
.