-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example for making the camera follow a target (#49)
- Loading branch information
Showing
1 changed file
with
97 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} | ||
} |