bevy-playground/src/camera.rs

95 lines
2.6 KiB
Rust
Raw Normal View History

2024-07-24 17:03:22 -05:00
use bevy::{
prelude::*,
sprite::{MaterialMesh2dBundle, Mesh2dHandle},
window::PrimaryWindow,
};
2023-12-25 15:35:10 -06:00
use crate::player::Player;
use bevy::render::camera::Camera as BevyCamera;
2024-07-24 17:03:22 -05:00
pub struct CameraPlugin;
2024-07-24 17:03:22 -05:00
impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, spawn)
2023-12-25 15:35:10 -06:00
.add_systems(PostUpdate, focus)
2024-07-24 17:03:22 -05:00
.add_systems(Update, y_sort)
.add_systems(Startup, spawn_crosshair)
.add_systems(Update, rotate_crosshair);
}
}
fn spawn(mut commands: Commands) {
let mut bundle = Camera2dBundle::default();
2023-12-25 15:22:15 -06:00
bundle.projection.scale = 1. / 2.;
commands.spawn(bundle);
}
2024-07-24 17:03:22 -05:00
#[derive(Component, Debug)]
pub struct Crosshair;
fn spawn_crosshair(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
let mesh = Mesh2dHandle(meshes.add(Capsule2d::new(3.0, 25.0)));
let material = materials.add(Color::hsl(360. * 1 as f32 / 3 as f32, 0.95, 0.7));
// let global_transform = GlobalTransform::from_xyz(
// 0.0, 20.0,
// // TODO: need some way to ensure this draws above everything else?
// // a UI layer or something?
// 1000.,
// );
let transform = Transform::from_xyz(
0.0, 0.0,
// TODO: need some way to ensure this draws above everything else?
// a UI layer or something?
1000.,
);
commands.spawn((
Crosshair,
MaterialMesh2dBundle {
// global_transform,
mesh,
material,
transform,
..default()
},
));
}
fn focus(
2023-12-25 15:35:10 -06:00
player: Query<&Transform, With<Player>>,
mut camera: Query<&mut Transform, (With<BevyCamera>, Without<Player>)>,
) {
2024-02-03 21:15:30 -06:00
let newpos = player.single().translation;
// println!("Cam pos: {newpos}");
camera.single_mut().translation = newpos
2023-12-25 15:35:10 -06:00
}
fn y_sort(mut q: Query<&mut Transform>) {
2024-05-17 09:57:24 -05:00
q.iter_mut()
.for_each(|mut tf| tf.translation.z = -tf.translation.y)
}
2024-07-24 17:03:22 -05:00
fn rotate_crosshair(
mut q: Query<&mut Transform, With<Crosshair>>,
win: Query<&Window, With<PrimaryWindow>>,
q_cam: Query<(&Camera, &GlobalTransform), With<Camera>>,
) {
let (camera, camera_transform) = q_cam.single();
if let Some(world_position) = win
.single()
.cursor_position()
.and_then(|cursor| camera.viewport_to_world(&GlobalTransform::from_xyz(0., 0., 0.), cursor))
.map(|ray| ray.origin.truncate())
{
let mut t = q.single_mut();
t.look_at(Vec3::ZERO, world_position.extend(0.));
t.translation = camera_transform.translation();
}
}