2580 Split examples PR feedback (#15181)
# Objective Applies feedback from previous PR #15135 'cause it got caught up in the merge train 🚂 I couldn't resist including roll, both for completeness and due to playing too many games that implemented it as a child. cc: @janhohenheim
This commit is contained in:
		
							parent
							
								
									e567669c31
								
							
						
					
					
						commit
						c454db88a3
					
				| @ -3266,7 +3266,6 @@ description = "Shows how to orbit a static scene using pitch, yaw, and roll." | |||||||
| category = "Camera" | category = "Camera" | ||||||
| wasm = true | wasm = true | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| [package.metadata.example.fps_overlay] | [package.metadata.example.fps_overlay] | ||||||
| name = "FPS overlay" | name = "FPS overlay" | ||||||
| description = "Demonstrates FPS overlay" | description = "Demonstrates FPS overlay" | ||||||
|  | |||||||
| @ -1,16 +1,36 @@ | |||||||
| //! Shows how to orbit camera around a static scene using pitch, yaw, and roll.
 | //! Shows how to orbit camera around a static scene using pitch, yaw, and roll.
 | ||||||
|  | //!
 | ||||||
|  | //! See also: `first_person_view_model` example, which does something similar but as a first-person
 | ||||||
|  | //! camera view.
 | ||||||
| 
 | 
 | ||||||
| use std::{f32::consts::FRAC_PI_2, ops::Range}; | use std::{f32::consts::FRAC_PI_2, ops::Range}; | ||||||
| 
 | 
 | ||||||
| use bevy::prelude::*; | use bevy::{input::mouse::AccumulatedMouseMotion, prelude::*}; | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Default, Resource)] | #[derive(Debug, Resource)] | ||||||
| struct CameraSettings { | struct CameraSettings { | ||||||
|     pub orbit_distance: f32, |     pub orbit_distance: f32, | ||||||
|     // Multiply keyboard inputs by this factor
 |     pub pitch_speed: f32, | ||||||
|     pub orbit_speed: f32, |  | ||||||
|     // Clamp pitch to this range
 |     // Clamp pitch to this range
 | ||||||
|     pub pitch_range: Range<f32>, |     pub pitch_range: Range<f32>, | ||||||
|  |     pub roll_speed: f32, | ||||||
|  |     pub yaw_speed: f32, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Default for CameraSettings { | ||||||
|  |     fn default() -> Self { | ||||||
|  |         // Limiting pitch stops some unexpected rotation past 90° up or down.
 | ||||||
|  |         let pitch_limit = FRAC_PI_2 - 0.01; | ||||||
|  |         Self { | ||||||
|  |             // These values are completely arbitrary, chosen because they seem to produce
 | ||||||
|  |             // "sensible" results for this example. Adjust as required.
 | ||||||
|  |             orbit_distance: 20.0, | ||||||
|  |             pitch_speed: 0.003, | ||||||
|  |             pitch_range: -pitch_limit..pitch_limit, | ||||||
|  |             roll_speed: 1.0, | ||||||
|  |             yaw_speed: 0.004, | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn main() { | fn main() { | ||||||
| @ -24,18 +44,10 @@ fn main() { | |||||||
| 
 | 
 | ||||||
| /// Set up a simple 3D scene
 | /// Set up a simple 3D scene
 | ||||||
| fn setup( | fn setup( | ||||||
|     mut camera_settings: ResMut<CameraSettings>, |  | ||||||
|     mut commands: Commands, |     mut commands: Commands, | ||||||
|     mut meshes: ResMut<Assets<Mesh>>, |     mut meshes: ResMut<Assets<Mesh>>, | ||||||
|     mut materials: ResMut<Assets<StandardMaterial>>, |     mut materials: ResMut<Assets<StandardMaterial>>, | ||||||
| ) { | ) { | ||||||
|     // Limiting pitch stops some unexpected rotation past 90° up or down.
 |  | ||||||
|     let pitch_limit = FRAC_PI_2 - 0.01; |  | ||||||
| 
 |  | ||||||
|     camera_settings.orbit_distance = 10.0; |  | ||||||
|     camera_settings.orbit_speed = 1.0; |  | ||||||
|     camera_settings.pitch_range = -pitch_limit..pitch_limit; |  | ||||||
| 
 |  | ||||||
|     commands.spawn(( |     commands.spawn(( | ||||||
|         Name::new("Camera"), |         Name::new("Camera"), | ||||||
|         Camera3dBundle { |         Camera3dBundle { | ||||||
| @ -94,15 +106,15 @@ fn instructions(mut commands: Commands) { | |||||||
|         )) |         )) | ||||||
|         .with_children(|parent| { |         .with_children(|parent| { | ||||||
|             parent.spawn(TextBundle::from_section( |             parent.spawn(TextBundle::from_section( | ||||||
|                 "W or S: pitch", |                 "Mouse up or down: pitch", | ||||||
|                 TextStyle::default(), |                 TextStyle::default(), | ||||||
|             )); |             )); | ||||||
|             parent.spawn(TextBundle::from_section( |             parent.spawn(TextBundle::from_section( | ||||||
|                 "A or D: yaw", |                 "Mouse left or right: yaw", | ||||||
|                 TextStyle::default(), |                 TextStyle::default(), | ||||||
|             )); |             )); | ||||||
|             parent.spawn(TextBundle::from_section( |             parent.spawn(TextBundle::from_section( | ||||||
|                 "Q or E: roll", |                 "Mouse buttons: roll", | ||||||
|                 TextStyle::default(), |                 TextStyle::default(), | ||||||
|             )); |             )); | ||||||
|         }); |         }); | ||||||
| @ -111,40 +123,29 @@ fn instructions(mut commands: Commands) { | |||||||
| fn orbit( | fn orbit( | ||||||
|     mut camera: Query<&mut Transform, With<Camera>>, |     mut camera: Query<&mut Transform, With<Camera>>, | ||||||
|     camera_settings: Res<CameraSettings>, |     camera_settings: Res<CameraSettings>, | ||||||
|     keyboard_input: Res<ButtonInput<KeyCode>>, |     mouse_buttons: Res<ButtonInput<MouseButton>>, | ||||||
|  |     mouse_motion: Res<AccumulatedMouseMotion>, | ||||||
|     time: Res<Time>, |     time: Res<Time>, | ||||||
| ) { | ) { | ||||||
|     let mut transform = camera.single_mut(); |     let mut transform = camera.single_mut(); | ||||||
| 
 |     let delta = mouse_motion.delta; | ||||||
|     let mut delta_pitch = 0.0; |  | ||||||
|     let mut delta_roll = 0.0; |     let mut delta_roll = 0.0; | ||||||
|     let mut delta_yaw = 0.0; |  | ||||||
| 
 | 
 | ||||||
|     if keyboard_input.pressed(KeyCode::KeyW) { |     if mouse_buttons.pressed(MouseButton::Left) { | ||||||
|         delta_pitch += camera_settings.orbit_speed; |         delta_roll -= 1.0; | ||||||
|     } |     } | ||||||
|     if keyboard_input.pressed(KeyCode::KeyS) { |     if mouse_buttons.pressed(MouseButton::Right) { | ||||||
|         delta_pitch -= camera_settings.orbit_speed; |         delta_roll += 1.0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if keyboard_input.pressed(KeyCode::KeyQ) { |     // Mouse motion is one of the few inputs that should not be multiplied by delta time,
 | ||||||
|         delta_roll -= camera_settings.orbit_speed; |     // as we are already receiving the full movement since the last frame was rendered. Multiplying
 | ||||||
|     } |     // by delta time here would make the movement slower that it should be.
 | ||||||
|     if keyboard_input.pressed(KeyCode::KeyE) { |     let delta_pitch = delta.y * camera_settings.pitch_speed; | ||||||
|         delta_roll += camera_settings.orbit_speed; |     let delta_yaw = delta.x * camera_settings.yaw_speed; | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if keyboard_input.pressed(KeyCode::KeyA) { |     // Conversely, we DO need to factor in delta time for mouse button inputs.
 | ||||||
|         delta_yaw -= camera_settings.orbit_speed; |     delta_roll *= camera_settings.roll_speed * time.delta_seconds(); | ||||||
|     } |  | ||||||
|     if keyboard_input.pressed(KeyCode::KeyD) { |  | ||||||
|         delta_yaw += camera_settings.orbit_speed; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Incorporating the delta time between calls prevents this from being framerate-bound.
 |  | ||||||
|     delta_pitch *= time.delta_seconds(); |  | ||||||
|     delta_roll *= time.delta_seconds(); |  | ||||||
|     delta_yaw *= time.delta_seconds(); |  | ||||||
| 
 | 
 | ||||||
|     // Obtain the existing pitch, yaw, and roll values from the transform.
 |     // Obtain the existing pitch, yaw, and roll values from the transform.
 | ||||||
|     let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ); |     let (yaw, pitch, roll) = transform.rotation.to_euler(EulerRot::YXZ); | ||||||
| @ -159,5 +160,7 @@ fn orbit( | |||||||
|     transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll); |     transform.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll); | ||||||
| 
 | 
 | ||||||
|     // Adjust the translation to maintain the correct orientation toward the orbit target.
 |     // Adjust the translation to maintain the correct orientation toward the orbit target.
 | ||||||
|     transform.translation = Vec3::ZERO - transform.forward() * camera_settings.orbit_distance; |     // In our example it's a static target, but this could easily be customised.
 | ||||||
|  |     let target = Vec3::ZERO; | ||||||
|  |     transform.translation = target - transform.forward() * camera_settings.orbit_distance; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Rich Churcher
						Rich Churcher