99 lines
2.8 KiB
Rust
99 lines
2.8 KiB
Rust
|
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<DebugCamOffset>, mut keys: ResMut<ButtonInput<KeyCode>>) {
|
||
|
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<CyberCameras>, Without<CyberBikeBody>)>,
|
||
|
bike: Query<&Transform, (With<CyberBikeBody>, Without<CyberCameras>)>,
|
||
|
offset: Res<DebugCamOffset>,
|
||
|
) {
|
||
|
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));
|
||
|
}
|
||
|
}
|