Skip to content

Commit

Permalink
Add example for making the camera follow a target (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
Plonq authored Feb 11, 2024
1 parent 4adf3dd commit 77bb7a9
Showing 1 changed file with 97 additions and 0 deletions.
97 changes: 97 additions & 0 deletions examples/follow_target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//! Demonstrates how to have the camera follow a target object
use bevy::prelude::*;
use bevy_panorbit_camera::{PanOrbitCamera, PanOrbitCameraPlugin};
use std::f32::consts::TAU;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(PanOrbitCameraPlugin)
.add_systems(Startup, setup)
.add_systems(Update, (animate_cube, cam_follow).chain())
.run();
}

#[derive(Component)]
struct Cube;

fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
// Ground
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0).into()),
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()),
..default()
});
// Cube
commands
.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
})
.insert(Cube);
// Light
commands.spawn(PointLightBundle {
point_light: PointLight {
intensity: 1500.0,
shadows_enabled: true,
..default()
},
transform: Transform::from_xyz(4.0, 8.0, 4.0),
..default()
});
// Camera
commands.spawn((
Camera3dBundle {
transform: Transform::from_translation(Vec3::new(0.0, 1.5, 5.0)),
..default()
},
PanOrbitCamera {
// Panning the camera changes the focus, and so you most likely want to disable
// panning when setting the focus manually
pan_sensitivity: 0.0,
// If you want to fully control the camera's focus, set smoothness to 0 so it
// immediately snaps to that location. If you want the 'follow' to be smoothed,
// leave this at default or set it to something between 0 and 1.
pan_smoothness: 0.0,
..default()
},
));
}

#[derive(Default)]
struct AnimateAngle(f32);

/// Move the cube in a circle around the Y axis
fn animate_cube(
time: Res<Time>,
mut cube_q: Query<&mut Transform, With<Cube>>,
mut angle: Local<AnimateAngle>,
) {
if let Ok(mut cube_tfm) = cube_q.get_single_mut() {
// Rotate 20 degrees a second, wrapping around to 0 after a full rotation
angle.0 += 20f32.to_radians() * time.delta_seconds() % TAU;
// Convert angle to position
let pos = Vec3::new(angle.0.sin() * 1.5, 0.5, angle.0.cos() * 1.5);
cube_tfm.translation = pos;
}
}

/// Set the camera's focus to the cube's position
fn cam_follow(mut pan_orbit_q: Query<&mut PanOrbitCamera>, cube_q: Query<&Transform, With<Cube>>) {
if let Ok(mut pan_orbit) = pan_orbit_q.get_single_mut() {
if let Ok(cube_tfm) = cube_q.get_single() {
pan_orbit.target_focus = cube_tfm.translation;
// Whenever changing properties manually like this, it's necessary to force
// PanOrbitCamera to update this frame (by default it only updates when there are
// input events).
pan_orbit.force_update = true;
}
}
}

0 comments on commit 77bb7a9

Please sign in to comment.