|
| 1 | +use bevy::{input::mouse::MouseWheel, prelude::*}; |
| 2 | + |
| 3 | +pub struct CameraPlugin; |
| 4 | + |
| 5 | +//Component that marks our Camera's current target |
| 6 | +#[derive(Component)] |
| 7 | +pub struct CameraTarget; |
| 8 | + |
| 9 | +//Component that marks our main camera |
| 10 | +#[derive(Component)] |
| 11 | +pub struct MainCamera; |
| 12 | + |
| 13 | +impl Plugin for CameraPlugin{ |
| 14 | + fn build(&self, app: &mut App){ |
| 15 | + app.add_systems(Startup, setup_main_camera); |
| 16 | + app.add_systems(Update, (update_camera, zoom_camera).chain()); |
| 17 | + } |
| 18 | +} |
| 19 | + |
| 20 | + |
| 21 | +//Sets up a 2d camera and attaches the MainCamera marker to it |
| 22 | +fn setup_main_camera( |
| 23 | + mut commands: Commands |
| 24 | +) { |
| 25 | + commands.spawn(( |
| 26 | + Camera2dBundle::default(), |
| 27 | + MainCamera |
| 28 | + )); |
| 29 | +} |
| 30 | + |
| 31 | + |
| 32 | +//Update camera function will have our main camera follow any entity with the CameraTarget tag |
| 33 | +fn update_camera( |
| 34 | + mut camera_query : Query<&mut Transform, (With<MainCamera>, Without<CameraTarget>)>, |
| 35 | + target_query: Query<&Transform, (With<CameraTarget>, Without<MainCamera>)>, |
| 36 | +){ |
| 37 | + //getting camera from query |
| 38 | + let Ok(mut camera) = camera_query.get_single_mut() else{ |
| 39 | + return; |
| 40 | + }; |
| 41 | + |
| 42 | + //getting target from query |
| 43 | + let Ok(target) = target_query.get_single() else{ |
| 44 | + return; |
| 45 | + }; |
| 46 | + |
| 47 | + //Gets the x and y coordinates of our target |
| 48 | + let Vec3 {x,y,..} = target.translation; |
| 49 | + |
| 50 | + //Stores the target x y with our camera z cuz our camera z not changing |
| 51 | + let direction = Vec3::new(x,y,camera.translation.z); |
| 52 | + |
| 53 | + //Debug statements if we want to use them :) |
| 54 | + //info!("Camera: {:?}", camera); |
| 55 | + //info!("Target: {:?}", target); |
| 56 | + |
| 57 | + //Make our camera translation match our target translation |
| 58 | + camera.translation = direction; |
| 59 | +} |
| 60 | + |
| 61 | +//Camera Zooming Function, uses MouseWheel Scrolling up/down for zooming in/out |
| 62 | +fn zoom_camera( |
| 63 | + mut scroll_event : EventReader<MouseWheel>, |
| 64 | + mut camera: Query<&mut OrthographicProjection, With<MainCamera>> |
| 65 | +){ |
| 66 | + |
| 67 | + |
| 68 | + //Zoom Sensitivity |
| 69 | + let zoom_factor = 0.1; |
| 70 | + |
| 71 | + //Amount to zoom in this update cycle |
| 72 | + let mut zoom_amount = 0.0; |
| 73 | + |
| 74 | + |
| 75 | + //For every event read in this cycle increase the zoom amount by 1 event * sensitivity |
| 76 | + for event in scroll_event.read(){ |
| 77 | + zoom_amount += -event.y * zoom_factor |
| 78 | + } |
| 79 | + |
| 80 | + //If we have had any mouse scroll events in this update then apply it to the camera projection |
| 81 | + if zoom_amount != 0.0{ |
| 82 | + //extracting the type of projection from camera, only ever going to be Orthographic since 2d but I don't know a better way lol |
| 83 | + for mut projection in camera.iter_mut(){ |
| 84 | + projection.scale += zoom_amount; |
| 85 | + |
| 86 | + //This statement makes sure that the amount of zoom is capped, can change if need be |
| 87 | + projection.scale = projection.scale.clamp(0.1,5.0); |
| 88 | + } |
| 89 | + } |
| 90 | +} |
0 commit comments