88 lines
3.0 KiB
Rust
88 lines
3.0 KiB
Rust
//! 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((
|
|
Mesh3d(meshes.add(Plane3d::default().mesh().size(0.5, 0.5))),
|
|
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))),
|
|
));
|
|
// Cube
|
|
commands
|
|
.spawn((
|
|
Mesh3d(meshes.add(Cuboid::new(0.1, 0.1, 0.1))),
|
|
MeshMaterial3d(materials.add(Color::srgb(0.8, 0.7, 0.6))),
|
|
Transform::from_xyz(0.0, 0.5, 0.0),
|
|
))
|
|
.insert(Cube);
|
|
// Light
|
|
commands.spawn((
|
|
PointLight {
|
|
shadows_enabled: true,
|
|
..default()
|
|
},
|
|
Transform::from_xyz(4.0, 8.0, 4.0),
|
|
));
|
|
// Camera
|
|
commands.spawn((
|
|
Transform::from_translation(Vec3::new(0.0, 0.15, 0.5)),
|
|
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()
|
|
},
|
|
));
|
|
}
|
|
|
|
/// 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<f32>,
|
|
) {
|
|
if let Ok(mut cube_tfm) = cube_q.single_mut() {
|
|
// Rotate 20 degrees a second, wrapping around to 0 after a full rotation
|
|
*angle += 20f32.to_radians() * time.delta_secs() % TAU;
|
|
// Convert angle to position
|
|
let pos = Vec3::new(angle.sin() * 0.15, 0.05, angle.cos() * 0.15);
|
|
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.single_mut() {
|
|
if let Ok(cube_tfm) = cube_q.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;
|
|
}
|
|
}
|
|
}
|