Editor fly camera

attempt/001
Elijah C. Voigt 1 year ago
parent 4bc704aff0
commit 63fab851ac

@ -0,0 +1,127 @@
use crate::prelude::*;
/// Menu Plugin; empty struct for Plugin impl
pub(crate) struct CameraPlugin;
impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
move_editor_fly_camera.run_if(any_with_component::<FlyCamera>),
);
app.add_systems(
Update,
rotate_editor_fly_camera.run_if(any_with_component::<FlyCamera>),
);
}
}
#[derive(Component)]
pub(crate) struct FlyCamera;
/// Fly camera system for moving around like a drone
/// TODO: Only if key is pressed!
fn move_editor_fly_camera(
mut cameras: Query<(&Camera, &mut Transform), With<FlyCamera>>,
windows: Query<&Window>,
primary_window: Query<Entity, With<PrimaryWindow>>,
keys: Res<ButtonInput<KeyCode>>,
time: Res<Time>,
) {
(keys.any_pressed([
KeyCode::KeyW,
KeyCode::KeyS,
KeyCode::KeyA,
KeyCode::KeyD,
KeyCode::KeyQ,
KeyCode::KeyE,
]))
.then(|| {
// Iterate over all cameras
cameras.iter_mut().for_each(|(c, mut t)| {
// Determine which window this camera is attached to
let target_window = match c.target {
RenderTarget::Window(wr) => match wr {
WindowRef::Entity(e) => Some(e),
WindowRef::Primary => Some(primary_window.get_single().unwrap()),
},
_ => None,
};
let window = windows.get(target_window.unwrap()).unwrap();
// If the target window is focused
window.focused.then(|| {
let move_speed = if keys.pressed(KeyCode::ShiftLeft) {
16.0
} else {
4.0
};
let mut delta = Vec3::ZERO;
if keys.pressed(KeyCode::KeyW) {
delta += t.forward() * move_speed * time.delta_seconds()
}
if keys.pressed(KeyCode::KeyS) {
delta += t.back() * move_speed * time.delta_seconds()
}
if keys.pressed(KeyCode::KeyA) {
delta += t.left() * move_speed * time.delta_seconds()
}
if keys.pressed(KeyCode::KeyD) {
delta += t.right() * move_speed * time.delta_seconds()
}
if keys.pressed(KeyCode::KeyE) {
delta += Vec3::Y * move_speed * time.delta_seconds()
}
if keys.pressed(KeyCode::KeyQ) {
delta += Vec3::NEG_Y * move_speed * time.delta_seconds()
}
t.translation += delta;
});
});
});
}
fn rotate_editor_fly_camera(
mut cameras: Query<(&Camera, &mut Transform), With<FlyCamera>>,
windows: Query<&Window>,
primary_window: Query<Entity, With<PrimaryWindow>>,
mouse: Res<ButtonInput<MouseButton>>,
mut cursor_events: EventReader<CursorMoved>,
) {
(cursor_events.len() > 0).then(|| {
// Iterate over all cameras
cameras.iter_mut().for_each(|(c, mut t)| {
// Determine which window this camera is attached to
let target_window = match c.target {
RenderTarget::Window(wr) => match wr {
WindowRef::Entity(e) => Some(e),
WindowRef::Primary => Some(primary_window.get_single().unwrap()),
},
_ => None,
};
let window = windows.get(target_window.unwrap()).unwrap();
if mouse.pressed(MouseButton::Middle) {
cursor_events
.read()
.filter_map(|CursorMoved { delta, window, .. }| {
(*window == target_window.unwrap()).then_some(delta)
})
.for_each(|delta| {
if let Some(Vec2 { x, y }) = delta {
// Cribbing from bevy_flycam
// Link: https://github.com/sburris0/bevy_flycam/blob/baffe50e0961ad1491d467fa6ab5551f9f21db8f/src/lib.rs#L145-L151
let (mut yaw, mut pitch, _) = t.rotation.to_euler(EulerRot::YXZ);
let window_scale = window.height().min(window.width());
let sensitivity = 0.00012;
pitch -= (sensitivity * y * window_scale).to_radians();
yaw -= (sensitivity * x * window_scale).to_radians();
t.rotation = Quat::from_axis_angle(Vec3::Y, yaw)
* Quat::from_axis_angle(Vec3::X, pitch);
}
});
} else {
cursor_events.clear();
}
});
});
}

@ -1,5 +1,8 @@
use bevy::prelude::*;
pub(crate) fn any_component_added<T: Component>(q: Query<Entity, Added<T>>) -> bool {
///
/// ECS scheduler active when an entity has a given component added
///
pub(crate) fn any_component_added<C: Component>(q: Query<Entity, Added<C>>) -> bool {
!q.is_empty()
}

@ -78,6 +78,7 @@ fn init_editor(mut commands: Commands) {
let editor_camera = commands
.spawn((
EditorTag,
FlyCamera,
Camera3dBundle {
camera: Camera {
target: RenderTarget::Window(WindowRef::Entity(editor_window)),
@ -180,7 +181,3 @@ fn plane_gizmos(mut gizmos: Gizmos) {
gizmos.arrow(Vec3::ZERO, Vec3::Z, Color::BLUE);
}
}
fn _fly_camera(mut _camera: Query<&mut Transform, (With<Camera>, With<EditorTag>)>) {
todo!()
}

@ -1,3 +1,5 @@
/// Camera controller
pub(crate) mod camera;
/// ECS scheduling `run_if` conditions
pub(crate) mod conditions;
/// Editor: debugging and run-time modifications to the game
@ -19,8 +21,9 @@ fn main() {
exit_condition: bevy::window::ExitCondition::OnPrimaryClosed,
..default()
}))
.add_plugins(menu::MenuPlugin)
.add_plugins(camera::CameraPlugin)
.add_plugins(editor::EditorPlugin)
.add_plugins(menu::MenuPlugin)
.add_plugins(window::WindowPlugin)
.run();
}

@ -6,4 +6,5 @@ pub(crate) use bevy::window::PrimaryWindow;
pub(crate) use bevy::window::WindowCloseRequested;
pub(crate) use bevy::window::WindowRef;
pub(crate) use crate::camera::*;
pub(crate) use crate::conditions::*;

Loading…
Cancel
Save