use bevy::{prelude::*, utils::HashSet}; use crate::bike::CyberBikeBody; #[derive(Component)] pub struct CyberCameras; #[derive(Debug, Resource)] pub struct DebugCamOffset { pub rot: f32, pub dist: f32, pub alt: f32, } impl Default for DebugCamOffset { fn default() -> Self { DebugCamOffset { rot: 60.0, dist: 10.0, alt: 4.0, } } } fn spawn_camera(mut commands: Commands) { commands .spawn(Camera3dBundle::default()) .insert(CyberCameras); } fn update_camera_pos(mut offset: ResMut, mut keys: ResMut>) { let keyset: HashSet<_> = keys.get_pressed().collect(); let shifted = keyset.contains(&KeyCode::ShiftLeft) || keyset.contains(&KeyCode::ShiftRight); for key in keyset { match key { KeyCode::ArrowLeft => offset.rot -= 5.0, KeyCode::ArrowRight => offset.rot += 5.0, KeyCode::ArrowUp => { if shifted { bevy::log::info!("up, shifted"); offset.alt += 0.5; } else { bevy::log::info!("up"); offset.dist -= 0.5; } } KeyCode::ArrowDown => { if shifted { bevy::log::info!("down, shifted"); offset.alt -= 0.5; } else { bevy::log::info!("down"); offset.dist += 0.5; } } _ => continue, } } let just_released: HashSet<_> = keys.get_just_released().cloned().collect(); if !just_released.is_empty() { let released_shift = just_released.contains(&KeyCode::ShiftLeft) || just_released.contains(&KeyCode::ShiftRight); keys.reset_all(); if !released_shift && shifted { keys.press(KeyCode::ShiftLeft); } } } fn follow_bike( mut camera: Query<&mut Transform, (With, Without)>, bike: Query<&Transform, (With, Without)>, offset: Res, ) { let bike_xform = *bike.single(); let up = Vec3::Y; let mut ncx = Transform::from_translation(bike_xform.translation); ncx.rotate(Quat::from_axis_angle(up, offset.rot.to_radians())); ncx.translation += ncx.forward() * offset.dist; ncx.translation += ncx.up() * offset.alt; ncx.look_at(bike_xform.translation, up); let mut cam_xform = camera.single_mut(); *cam_xform = ncx; } pub struct CamPlug; impl Plugin for CamPlug { fn build(&self, app: &mut App) { app.insert_resource(DebugCamOffset::default()) .add_systems(Startup, spawn_camera) .add_systems(Update, (follow_bike, update_camera_pos)); } }