Use AccumulatedMouseMotion, AccumulatedMouseScroll in examples (#14488)

# Objective

Use the new `AccumulatedMouseMotion` and `AccumulatedMouseScroll`
resources in place of mouse event handling.

I left the `mouse_input_events` example alone, since by its nature it
demonstrates event detection.

Fixes #14066 

## Testing

Ran each example locally before and after changes.
This commit is contained in:
Rich Churcher 2024-07-30 11:38:59 +12:00 committed by GitHub
parent 601cf6b9e5
commit 848e7fae43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 53 additions and 59 deletions

View File

@ -43,7 +43,7 @@
//! | arrow down | Increase FOV | //! | arrow down | Increase FOV |
use bevy::color::palettes::tailwind; use bevy::color::palettes::tailwind;
use bevy::input::mouse::MouseMotion; use bevy::input::mouse::AccumulatedMouseMotion;
use bevy::pbr::NotShadowCaster; use bevy::pbr::NotShadowCaster;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::view::RenderLayers; use bevy::render::view::RenderLayers;
@ -219,13 +219,15 @@ fn spawn_text(mut commands: Commands) {
} }
fn move_player( fn move_player(
mut mouse_motion: EventReader<MouseMotion>, accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
mut player: Query<&mut Transform, With<Player>>, mut player: Query<&mut Transform, With<Player>>,
) { ) {
let mut transform = player.single_mut(); let mut transform = player.single_mut();
for motion in mouse_motion.read() { let delta = accumulated_mouse_motion.delta;
let yaw = -motion.delta.x * 0.003;
let pitch = -motion.delta.y * 0.002; if delta != Vec2::ZERO {
let yaw = -delta.x * 0.003;
let pitch = -delta.y * 0.002;
// Order of rotations is important, see <https://gamedev.stackexchange.com/a/136175/103059> // Order of rotations is important, see <https://gamedev.stackexchange.com/a/136175/103059>
transform.rotate_y(yaw); transform.rotate_y(yaw);
transform.rotate_local_x(pitch); transform.rotate_local_x(pitch);

View File

@ -3,7 +3,7 @@
//! - Copy the code for the [`CameraControllerPlugin`] and add the plugin to your App. //! - Copy the code for the [`CameraControllerPlugin`] and add the plugin to your App.
//! - Attach the [`CameraController`] component to an entity with a [`Camera3dBundle`]. //! - Attach the [`CameraController`] component to an entity with a [`Camera3dBundle`].
use bevy::input::mouse::{MouseMotion, MouseScrollUnit, MouseWheel}; use bevy::input::mouse::{AccumulatedMouseMotion, AccumulatedMouseScroll, MouseScrollUnit};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::window::CursorGrabMode; use bevy::window::CursorGrabMode;
use std::{f32::consts::*, fmt}; use std::{f32::consts::*, fmt};
@ -101,8 +101,8 @@ Freecam Controls:
fn run_camera_controller( fn run_camera_controller(
time: Res<Time>, time: Res<Time>,
mut windows: Query<&mut Window>, mut windows: Query<&mut Window>,
mut mouse_events: EventReader<MouseMotion>, accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
mut scroll_events: EventReader<MouseWheel>, accumulated_mouse_scroll: Res<AccumulatedMouseScroll>,
mouse_button_input: Res<ButtonInput<MouseButton>>, mouse_button_input: Res<ButtonInput<MouseButton>>,
key_input: Res<ButtonInput<KeyCode>>, key_input: Res<ButtonInput<KeyCode>>,
mut toggle_cursor_grab: Local<bool>, mut toggle_cursor_grab: Local<bool>,
@ -120,18 +120,16 @@ fn run_camera_controller(
info!("{}", *controller); info!("{}", *controller);
} }
if !controller.enabled { if !controller.enabled {
mouse_events.clear();
return; return;
} }
let mut scroll = 0.0; let mut scroll = 0.0;
for scroll_event in scroll_events.read() {
let amount = match scroll_event.unit { let amount = match accumulated_mouse_scroll.unit {
MouseScrollUnit::Line => scroll_event.y, MouseScrollUnit::Line => accumulated_mouse_scroll.delta.y,
MouseScrollUnit::Pixel => scroll_event.y / 16.0, MouseScrollUnit::Pixel => accumulated_mouse_scroll.delta.y / 16.0,
}; };
scroll += amount; scroll += amount;
}
controller.walk_speed += scroll * controller.scroll_factor * controller.walk_speed; controller.walk_speed += scroll * controller.scroll_factor * controller.walk_speed;
controller.run_speed = controller.walk_speed * 3.0; controller.run_speed = controller.walk_speed * 3.0;
@ -212,21 +210,13 @@ fn run_camera_controller(
} }
// Handle mouse input // Handle mouse input
let mut mouse_delta = Vec2::ZERO; if accumulated_mouse_motion.delta != Vec2::ZERO && cursor_grab {
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 // Apply look update
controller.pitch = (controller.pitch controller.pitch = (controller.pitch
- mouse_delta.y * RADIANS_PER_DOT * controller.sensitivity) - accumulated_mouse_motion.delta.y * RADIANS_PER_DOT * controller.sensitivity)
.clamp(-PI / 2., PI / 2.); .clamp(-PI / 2., PI / 2.);
controller.yaw -= mouse_delta.x * RADIANS_PER_DOT * controller.sensitivity; controller.yaw -=
accumulated_mouse_motion.delta.x * RADIANS_PER_DOT * controller.sensitivity;
transform.rotation = transform.rotation =
Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch); Quat::from_euler(EulerRot::ZYX, 0.0, controller.yaw, controller.pitch);
} }

View File

@ -1,7 +1,7 @@
//! This example shows how to sample random points from primitive shapes. //! This example shows how to sample random points from primitive shapes.
use bevy::{ use bevy::{
input::mouse::{MouseButtonInput, MouseMotion}, input::mouse::{AccumulatedMouseMotion, MouseButtonInput},
math::prelude::*, math::prelude::*,
prelude::*, prelude::*,
render::mesh::SphereKind, render::mesh::SphereKind,
@ -119,7 +119,7 @@ fn setup(
R: Restart (erase all samples).\n\ R: Restart (erase all samples).\n\
S: Add one random sample.\n\ S: Add one random sample.\n\
D: Add 100 random samples.\n\ D: Add 100 random samples.\n\
Rotate camera by panning left/right.", Rotate camera by holding left mouse and panning left/right.",
TextStyle::default(), TextStyle::default(),
) )
.with_style(Style { .with_style(Style {
@ -230,8 +230,8 @@ fn handle_keypress(
// Handle user mouse input for panning the camera around: // Handle user mouse input for panning the camera around:
fn handle_mouse( fn handle_mouse(
accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
mut button_events: EventReader<MouseButtonInput>, mut button_events: EventReader<MouseButtonInput>,
mut motion_events: EventReader<MouseMotion>,
mut camera: Query<&mut Transform, With<Camera>>, mut camera: Query<&mut Transform, With<Camera>>,
mut mouse_pressed: ResMut<MousePressed>, mut mouse_pressed: ResMut<MousePressed>,
) { ) {
@ -247,7 +247,9 @@ fn handle_mouse(
if !mouse_pressed.0 { if !mouse_pressed.0 {
return; return;
} }
let displacement: f32 = motion_events.read().map(|motion| motion.delta.x).sum(); if accumulated_mouse_motion.delta != Vec2::ZERO {
let mut camera_transform = camera.single_mut(); let displacement = accumulated_mouse_motion.delta.x;
camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 150.)); let mut camera_transform = camera.single_mut();
camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 150.));
}
} }

View File

@ -4,7 +4,7 @@ use std::f32::consts::PI;
use bevy::{ use bevy::{
core_pipeline::{bloom::BloomSettings, tonemapping::Tonemapping}, core_pipeline::{bloom::BloomSettings, tonemapping::Tonemapping},
input::mouse::{MouseButtonInput, MouseMotion, MouseWheel}, input::mouse::{AccumulatedMouseMotion, AccumulatedMouseScroll, MouseButtonInput},
math::prelude::*, math::prelude::*,
prelude::*, prelude::*,
}; };
@ -392,7 +392,7 @@ fn setup(
R: Restart (erase all samples).\n\ R: Restart (erase all samples).\n\
S: Add one random sample.\n\ S: Add one random sample.\n\
D: Add 100 random samples.\n\ D: Add 100 random samples.\n\
Rotate camera by panning via mouse.\n\ Rotate camera by holding left mouse and panning.\n\
Zoom camera by scrolling via mouse or +/-.\n\ Zoom camera by scrolling via mouse or +/-.\n\
Move camera by L/R arrow keys.\n\ Move camera by L/R arrow keys.\n\
Tab: Toggle this text", Tab: Toggle this text",
@ -523,9 +523,9 @@ fn handle_keypress(
// Handle user mouse input for panning the camera around: // Handle user mouse input for panning the camera around:
fn handle_mouse( fn handle_mouse(
accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
accumulated_mouse_scroll: Res<AccumulatedMouseScroll>,
mut button_events: EventReader<MouseButtonInput>, mut button_events: EventReader<MouseButtonInput>,
mut motion_events: EventReader<MouseMotion>,
mut scroll_events: EventReader<MouseWheel>,
mut camera: Query<&mut CameraRig>, mut camera: Query<&mut CameraRig>,
mut mouse_pressed: ResMut<MousePressed>, mut mouse_pressed: ResMut<MousePressed>,
) { ) {
@ -539,25 +539,25 @@ fn handle_mouse(
let mut camera_rig = camera.single_mut(); let mut camera_rig = camera.single_mut();
let mouse_scroll = scroll_events if accumulated_mouse_scroll.delta != Vec2::ZERO {
.read() let mouse_scroll = accumulated_mouse_scroll.delta.y;
.fold(0.0, |acc, scroll_event| acc + scroll_event.y); camera_rig.distance -= mouse_scroll / 15.0 * MAX_CAMERA_DISTANCE;
camera_rig.distance -= mouse_scroll / 15.0 * MAX_CAMERA_DISTANCE; camera_rig.distance = camera_rig
camera_rig.distance = camera_rig .distance
.distance .clamp(MIN_CAMERA_DISTANCE, MAX_CAMERA_DISTANCE);
.clamp(MIN_CAMERA_DISTANCE, MAX_CAMERA_DISTANCE); }
// If the mouse is not pressed, just ignore motion events // If the mouse is not pressed, just ignore motion events
if !mouse_pressed.0 { if !mouse_pressed.0 {
return; return;
} }
let displacement = motion_events if accumulated_mouse_motion.delta != Vec2::ZERO {
.read() let displacement = accumulated_mouse_motion.delta;
.fold(Vec2::ZERO, |acc, mouse_motion| acc + mouse_motion.delta); camera_rig.yaw += displacement.x / 90.;
camera_rig.yaw += displacement.x / 90.; camera_rig.pitch += displacement.y / 90.;
camera_rig.pitch += displacement.y / 90.; // The extra 0.01 is to disallow weird behaviour at the poles of the rotation
// The extra 0.01 is to disallow weird behaviour at the poles of the rotation camera_rig.pitch = camera_rig.pitch.clamp(-PI / 2.01, PI / 2.01);
camera_rig.pitch = camera_rig.pitch.clamp(-PI / 2.01, PI / 2.01); }
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]

View File

@ -1,7 +1,7 @@
//! This example shows how to align the orientations of objects in 3D space along two axes using the `Transform::align` API. //! This example shows how to align the orientations of objects in 3D space along two axes using the `Transform::align` API.
use bevy::color::palettes::basic::{GRAY, RED, WHITE}; use bevy::color::palettes::basic::{GRAY, RED, WHITE};
use bevy::input::mouse::{MouseButtonInput, MouseMotion}; use bevy::input::mouse::{AccumulatedMouseMotion, MouseButtonInput};
use bevy::prelude::*; use bevy::prelude::*;
use rand::{Rng, SeedableRng}; use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng; use rand_chacha::ChaCha8Rng;
@ -209,8 +209,8 @@ fn handle_keypress(
// Handle user mouse input for panning the camera around // Handle user mouse input for panning the camera around
fn handle_mouse( fn handle_mouse(
accumulated_mouse_motion: Res<AccumulatedMouseMotion>,
mut button_events: EventReader<MouseButtonInput>, mut button_events: EventReader<MouseButtonInput>,
mut motion_events: EventReader<MouseMotion>,
mut camera: Query<&mut Transform, With<Camera>>, mut camera: Query<&mut Transform, With<Camera>>,
mut mouse_pressed: ResMut<MousePressed>, mut mouse_pressed: ResMut<MousePressed>,
) { ) {
@ -226,11 +226,11 @@ fn handle_mouse(
if !mouse_pressed.0 { if !mouse_pressed.0 {
return; return;
} }
let displacement = motion_events if accumulated_mouse_motion.delta != Vec2::ZERO {
.read() let displacement = accumulated_mouse_motion.delta.x;
.fold(0., |acc, mouse_motion| acc + mouse_motion.delta.x); let mut camera_transform = camera.single_mut();
let mut camera_transform = camera.single_mut(); camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 75.));
camera_transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(-displacement / 75.)); }
} }
// Helper functions (i.e. non-system functions) // Helper functions (i.e. non-system functions)