Skip to content

Commit 758476e

Browse files
authored
Add support for using real time (#125)
1 parent 9cd3cbd commit 758476e

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

examples/keyboard_controls.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ fn setup(
5050
}
5151

5252
fn keyboard_controls(
53+
// If you set `PanOrbitCamera::use_real_time` to `true`, you may want to use `Res<Time<Real>>`
54+
// here too, so you can control the camera while virtual time is paused.
5355
time: Res<Time>,
5456
key_input: Res<ButtonInput<KeyCode>>,
5557
mut pan_orbit_query: Query<(&mut PanOrbitCamera, &mut Transform)>,

examples/pausing.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//! Demonstrates how to pause time without affecting the camera
2+
3+
use bevy::prelude::*;
4+
use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin};
5+
6+
fn main() {
7+
App::new()
8+
.add_plugins(DefaultPlugins)
9+
.add_plugins(PanOrbitCameraPlugin)
10+
.add_systems(Startup, setup)
11+
.add_systems(Update, (pause_game_system, cube_rotator_system))
12+
.run();
13+
}
14+
15+
#[derive(Component)]
16+
struct Cube;
17+
18+
fn setup(
19+
mut commands: Commands,
20+
mut meshes: ResMut<Assets<Mesh>>,
21+
mut materials: ResMut<Assets<StandardMaterial>>,
22+
) {
23+
// Ground
24+
commands.spawn((
25+
Mesh3d(meshes.add(Plane3d::default().mesh().size(5.0, 5.0))),
26+
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
27+
));
28+
// Cube
29+
commands.spawn((
30+
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
31+
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
32+
Transform::from_xyz(0.0, 0.5, 0.0),
33+
Cube,
34+
));
35+
// Light
36+
commands.spawn((
37+
PointLight {
38+
shadows_enabled: true,
39+
..default()
40+
},
41+
Transform::from_xyz(4.0, 8.0, 4.0),
42+
));
43+
// Camera
44+
commands.spawn((
45+
Transform::from_xyz(0.0, 1.5, 5.0),
46+
PanOrbitCamera {
47+
use_real_time: true,
48+
..default()
49+
},
50+
));
51+
// Help text
52+
commands.spawn(Text::new(
53+
"\
54+
Press Space to pause the 'game'",
55+
));
56+
}
57+
58+
// Pauses the game (i.e. virtual time)
59+
fn pause_game_system(key_input: Res<ButtonInput<KeyCode>>, mut time: ResMut<Time<Virtual>>) {
60+
if key_input.just_pressed(KeyCode::Space) {
61+
if time.is_paused() {
62+
time.unpause()
63+
} else {
64+
time.pause()
65+
}
66+
}
67+
}
68+
69+
// Rotates the cube so you can see the effect of pausing time
70+
// Note the default time for the Update schedule is `Time<Virtual>`
71+
fn cube_rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<Cube>>) {
72+
for mut transform in &mut query {
73+
transform.rotate_y(1.0 * time.delta_secs());
74+
}
75+
}

src/lib.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ pub struct PanOrbitCamera {
270270
/// up direction. The default up is Y, but if you want the camera rotated.
271271
/// The axis can be switched. Default is [Vec3::X, Vec3::Y, Vec3::Z]
272272
pub axis: [Vec3; 3],
273+
/// Use real time instead of virtual time. Set this to `true` if you want to pause virtual
274+
/// time without affecting the camera, for example in a game.
275+
/// Defaults to `false`.
276+
pub use_real_time: bool,
273277
}
274278

275279
impl Default for PanOrbitCamera {
@@ -313,6 +317,7 @@ impl Default for PanOrbitCamera {
313317
zoom_lower_limit: 0.05,
314318
force_update: false,
315319
axis: [Vec3::X, Vec3::Y, Vec3::Z],
320+
use_real_time: false,
316321
}
317322
}
318323
}
@@ -484,7 +489,8 @@ fn pan_orbit_camera(
484489
mouse_key_tracker: Res<MouseKeyTracker>,
485490
touch_tracker: Res<TouchTracker>,
486491
mut orbit_cameras: Query<(Entity, &mut PanOrbitCamera, &mut Transform, &mut Projection)>,
487-
time: Res<Time>,
492+
time_real: Res<Time<Real>>,
493+
time_virt: Res<Time<Virtual>>,
488494
) {
489495
for (entity, mut pan_orbit, mut transform, mut projection) in orbit_cameras.iter_mut() {
490496
// Closures that apply limits to the yaw, pitch, and zoom values
@@ -704,6 +710,12 @@ fn pan_orbit_camera(
704710

705711
// 4 - Update the camera's transform based on current values
706712

713+
let delta = if pan_orbit.use_real_time {
714+
time_real.delta_secs()
715+
} else {
716+
time_virt.delta_secs()
717+
};
718+
707719
if let (Some(yaw), Some(pitch), Some(radius)) =
708720
(pan_orbit.yaw, pan_orbit.pitch, pan_orbit.radius)
709721
{
@@ -723,25 +735,25 @@ fn pan_orbit_camera(
723735
yaw,
724736
pan_orbit.target_yaw,
725737
pan_orbit.orbit_smoothness,
726-
time.delta_secs(),
738+
delta,
727739
);
728740
let new_pitch = util::lerp_and_snap_f32(
729741
pitch,
730742
pan_orbit.target_pitch,
731743
pan_orbit.orbit_smoothness,
732-
time.delta_secs(),
744+
delta,
733745
);
734746
let new_radius = util::lerp_and_snap_f32(
735747
radius,
736748
pan_orbit.target_radius,
737749
pan_orbit.zoom_smoothness,
738-
time.delta_secs(),
750+
delta,
739751
);
740752
let new_focus = util::lerp_and_snap_vec3(
741753
pan_orbit.focus,
742754
pan_orbit.target_focus,
743755
pan_orbit.pan_smoothness,
744-
time.delta_secs(),
756+
delta,
745757
);
746758

747759
util::update_orbit_transform(

0 commit comments

Comments
 (0)