From 3ed9e277fd209958bcc8b01835132ad131b9058b Mon Sep 17 00:00:00 2001 From: Carter Hollman Date: Wed, 23 Oct 2024 00:03:27 -0700 Subject: [PATCH 1/3] feat: Complete camera system w/ smoothing --- game/src/camera.rs | 1 + game/src/camera/camera_plugin.rs | 77 ++++++++++++++++++++++++++++++++ game/src/main.rs | 3 ++ 3 files changed, 81 insertions(+) create mode 100644 game/src/camera.rs create mode 100644 game/src/camera/camera_plugin.rs diff --git a/game/src/camera.rs b/game/src/camera.rs new file mode 100644 index 0000000..e2fc46d --- /dev/null +++ b/game/src/camera.rs @@ -0,0 +1 @@ +pub mod camera_plugin; diff --git a/game/src/camera/camera_plugin.rs b/game/src/camera/camera_plugin.rs new file mode 100644 index 0000000..bcbd0f5 --- /dev/null +++ b/game/src/camera/camera_plugin.rs @@ -0,0 +1,77 @@ +use avian2d::prelude::*; +use bevy::{input::mouse::MouseWheel, prelude::*}; + +pub struct CameraPlugin; + +//Component that marks our Camera's current target +#[derive(Component)] +pub struct CameraTarget; + +//Component that marks our main camera +#[derive(Component)] +pub struct MainCamera; + +impl Plugin for CameraPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Startup, setup_main_camera); + app.add_systems( + PostUpdate, + update_camera + .after(PhysicsSet::Sync) + .before(TransformSystem::TransformPropagate), + ); + app.add_systems(Update, zoom_camera); + } +} + +//Sets up a 2d camera and attaches the MainCamera marker to it +fn setup_main_camera(mut commands: Commands) { + commands.spawn((Camera2dBundle::default(), MainCamera)); +} + +//Update camera function will have our main camera follow any entity with the CameraTarget tag +fn update_camera( + mut camera_query: Query<&mut Transform, (With, Without)>, + target_query: Query<&Transform, (With, Without)>, +) { + let Ok(mut camera) = camera_query.get_single_mut() else { + error!("could not execute query for single MainCamera component"); + return; + }; + + let Ok(target) = target_query.get_single() else { + error!("Could not execute query for single CameraTarget component"); + return; + }; + + let Vec3 { x, y, .. } = target.translation; + + let direction = Vec3::new(x, y, camera.translation.z); + + camera.translation = direction; +} + +//Camera Zooming Function, uses MouseWheel Scrolling up/down for zooming in/out +fn zoom_camera( + mut scroll_event: EventReader, + mut camera: Query<&mut OrthographicProjection, With>, +) { + //Zoom Sensitivity + let zoom_factor = 0.1; + + //Amount to zoom in this update cycle + let mut zoom_amount = 0.0; + + for event in scroll_event.read() { + zoom_amount += -event.y * zoom_factor + } + + if zoom_amount != 0.0 { + for mut projection in camera.iter_mut() { + projection.scale += zoom_amount; + + //This statement makes sure that the amount of zoom is capped, can change if need be + projection.scale = projection.scale.clamp(0.1, 5.0); + } + } +} diff --git a/game/src/main.rs b/game/src/main.rs index 37d9f19..b01d9b9 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -1,9 +1,11 @@ +mod camera; mod debug; mod movement; use avian2d::prelude::*; use bevy::prelude::*; use bevy_ecs_ldtk::prelude::*; +use camera::camera_plugin::CameraPlugin; use debug::debug_plugin::DebugPlugin; use movement::plugin::CharacterControllerPlugin; @@ -15,5 +17,6 @@ fn main() { .add_plugins(CharacterControllerPlugin) //user plugins .add_plugins(DebugPlugin) + .add_plugins(CameraPlugin) .run(); } From c86c6ae8b65c8385d6311a64eef8e0efd16cfeab Mon Sep 17 00:00:00 2001 From: Carter Hollman Date: Sat, 26 Oct 2024 21:43:01 -0700 Subject: [PATCH 2/3] fix: formatting --- game/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game/src/main.rs b/game/src/main.rs index 4a2e4e7..a97476a 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -1,6 +1,6 @@ #![allow(unused)] -mod camera; mod animation; +mod camera; mod components; mod debug; mod movement; From dcc40032ceede73d3a9c49bef69487d93ca0ac38 Mon Sep 17 00:00:00 2001 From: Carter Hollman Date: Tue, 5 Nov 2024 01:31:13 -0800 Subject: [PATCH 3/3] fix:rustdoc + bugfix --- game/src/camera/camera_plugin.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/game/src/camera/camera_plugin.rs b/game/src/camera/camera_plugin.rs index bcbd0f5..cdb2dd5 100644 --- a/game/src/camera/camera_plugin.rs +++ b/game/src/camera/camera_plugin.rs @@ -3,11 +3,11 @@ use bevy::{input::mouse::MouseWheel, prelude::*}; pub struct CameraPlugin; -//Component that marks our Camera's current target +///Component that marks the Camera's current target #[derive(Component)] pub struct CameraTarget; -//Component that marks our main camera +///Component that marks the main camera #[derive(Component)] pub struct MainCamera; @@ -24,23 +24,29 @@ impl Plugin for CameraPlugin { } } -//Sets up a 2d camera and attaches the MainCamera marker to it +///Sets up a 2d camera and attaches the MainCamera marker to it fn setup_main_camera(mut commands: Commands) { commands.spawn((Camera2dBundle::default(), MainCamera)); } -//Update camera function will have our main camera follow any entity with the CameraTarget tag +///Update camera function will have the main camera follow any entity with the CameraTarget tag fn update_camera( mut camera_query: Query<&mut Transform, (With, Without)>, target_query: Query<&Transform, (With, Without)>, ) { + let num_targets = target_query.iter().len(); + + if (num_targets > 1) { + error!("More than one entity with CameraTarget Component!"); + return; + } + let Ok(mut camera) = camera_query.get_single_mut() else { - error!("could not execute query for single MainCamera component"); + error!("Could not execute query for single MainCamera component"); return; }; let Ok(target) = target_query.get_single() else { - error!("Could not execute query for single CameraTarget component"); return; }; @@ -51,7 +57,7 @@ fn update_camera( camera.translation = direction; } -//Camera Zooming Function, uses MouseWheel Scrolling up/down for zooming in/out +///Camera Zooming Function, uses MouseWheel Scrolling up/down for zooming in/out fn zoom_camera( mut scroll_event: EventReader, mut camera: Query<&mut OrthographicProjection, With>,