parent
df8cc62ece
commit
1458958ba2
9 changed files with 169 additions and 98 deletions
@ -0,0 +1,38 @@ |
||||
use bevy::prelude::*; |
||||
use common::prelude::*; |
||||
|
||||
pub fn plugin(app: &mut App) { |
||||
app.load_resource::<PlayerAssets>(); |
||||
app.add_observer(insert_player_visuals); |
||||
} |
||||
|
||||
#[derive(Resource, Asset, Reflect, Clone)] |
||||
#[reflect(Resource)] |
||||
pub struct PlayerAssets { |
||||
#[dependency] |
||||
mesh: Handle<Mesh>, |
||||
#[dependency] |
||||
material: Handle<StandardMaterial>, |
||||
} |
||||
|
||||
impl FromWorld for PlayerAssets { |
||||
fn from_world(world: &mut World) -> Self { |
||||
let assets = world.resource::<AssetServer>(); |
||||
Self { |
||||
mesh: assets.add(Cuboid::new(1.0, 1.0, 1.0).into()), |
||||
material: assets.add(Color::srgb_u8(124, 255, 144).into()), |
||||
} |
||||
} |
||||
} |
||||
|
||||
fn insert_player_visuals( |
||||
event: On<Add, Player>, |
||||
mut commands: Commands, |
||||
block_assets: Res<PlayerAssets>, |
||||
) { |
||||
let player = event.entity; |
||||
commands.entity(player).insert(( |
||||
Mesh3d(block_assets.mesh.clone()), |
||||
MeshMaterial3d(block_assets.material.clone()), |
||||
)); |
||||
} |
||||
@ -1,56 +0,0 @@ |
||||
use std::f32::consts::TAU; |
||||
|
||||
use bevy::prelude::*; |
||||
|
||||
use bevy::input::mouse::AccumulatedMouseMotion; |
||||
|
||||
#[derive(Component, Debug)] |
||||
pub struct CameraFreeLook { |
||||
/// The mouse sensitivity, in radians per pixel.
|
||||
pub sensitivity: Vec2, |
||||
/// How far the camera can be tilted up and down.
|
||||
pub pitch_limit: std::ops::RangeInclusive<f32>, |
||||
|
||||
/// Upon initialization, `pitch` and `yaw` will
|
||||
/// be set from the camera transform's rotation.
|
||||
initialized: bool, |
||||
/// The current yaw (right/left) of the camera, in radians.
|
||||
pub yaw: f32, |
||||
/// The current pitch (tilt) of the camera, in radians.
|
||||
pub pitch: f32, |
||||
} |
||||
|
||||
impl Default for CameraFreeLook { |
||||
fn default() -> Self { |
||||
Self { |
||||
sensitivity: Vec2::splat(0.2).map(f32::to_radians), |
||||
pitch_limit: -(TAU / 4.0)..=(TAU / 4.0), |
||||
initialized: false, |
||||
yaw: 0.0, |
||||
pitch: 0.0, |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub fn camera_look( |
||||
accumulated_mouse_motion: Res<AccumulatedMouseMotion>, |
||||
camera: Single<(&mut Transform, &mut CameraFreeLook)>, |
||||
) { |
||||
let (mut transform, mut look) = camera.into_inner(); |
||||
|
||||
// Ensure the yaw and pitch are initialized once
|
||||
// from the camera transform's current rotation.
|
||||
if !look.initialized { |
||||
(look.yaw, look.pitch, _) = transform.rotation.to_euler(EulerRot::YXZ); |
||||
look.initialized = true; |
||||
} |
||||
|
||||
// Update the current camera state's internal yaw and pitch.
|
||||
let motion = accumulated_mouse_motion.delta * look.sensitivity; |
||||
let (min, max) = look.pitch_limit.clone().into_inner(); |
||||
look.yaw = (look.yaw - motion.x).rem_euclid(TAU); // keep within 0°..360°
|
||||
look.pitch = (look.pitch - motion.y).clamp(min, max); |
||||
|
||||
// Override the camera transform's rotation.
|
||||
transform.rotation = Quat::from_euler(EulerRot::ZYX, 0.0, look.yaw, look.pitch); |
||||
} |
||||
@ -0,0 +1,30 @@ |
||||
use bevy::prelude::*; |
||||
use common::prelude::*; |
||||
use lightyear::prelude::input::native::*; |
||||
|
||||
use bevy::input::mouse::AccumulatedMouseMotion; |
||||
|
||||
use crate::input::is_cursor_grabbed; |
||||
|
||||
#[derive(Resource, Deref, DerefMut, Debug)] |
||||
pub struct MouseSensitivity(Vec2); |
||||
|
||||
impl Default for MouseSensitivity { |
||||
fn default() -> Self { |
||||
Self(Vec2::splat(0.2).map(f32::to_radians)) |
||||
} |
||||
} |
||||
|
||||
pub fn plugin(app: &mut App) { |
||||
app.init_resource::<MouseSensitivity>(); |
||||
app.add_systems(Update, update_head_orientation.run_if(is_cursor_grabbed)); |
||||
} |
||||
|
||||
fn update_head_orientation( |
||||
accumulated_mouse_motion: Res<AccumulatedMouseMotion>, |
||||
mouse_sensitivity: Res<MouseSensitivity>, |
||||
mut orientation: Single<&mut HeadOrientation, With<InputMarker<Inputs>>>, |
||||
) { |
||||
let delta = accumulated_mouse_motion.delta * **mouse_sensitivity; |
||||
**orientation = orientation.update(delta); |
||||
} |
||||
Loading…
Reference in new issue