diff --git a/README.md b/README.md index fcaaf3d..b9ba3cf 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Key features: - t: toggle music (NOTE: currently no music is included in the git repo) - m: mute sound effects - q: enter/exit vehicle +- f: toggle 3rd person view - TAB: toggle augmented reality overlay (HUD, low-light amplifier) # System Requirements diff --git a/src/actor.rs b/src/actor.rs index 71848ca..ce451e3 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -64,6 +64,7 @@ pub struct Actor { pub v: Vec3, // velocity pub angular_momentum: Quat, pub inside_entity: u32, + pub camdistance: f32, } impl Default for Actor { @@ -75,12 +76,14 @@ impl Default for Actor { v: Vec3::ZERO, inside_entity: NO_RIDE, angular_momentum: Quat::from_euler(EulerRot::XYZ, 0.001, 0.01, 0.003), + camdistance: 10.0, } } } -#[derive(Component)] pub struct Player; -#[derive(Component)] pub struct PlayerDrivesThis; +#[derive(Component)] pub struct Player; // Attached to the suit of the player +#[derive(Component)] pub struct PlayerDrivesThis; // Attached to the entered vehicle +#[derive(Component)] pub struct PlayerCamera; // Attached to the actor to use as point of view #[derive(Component)] pub struct PlayerInConversation; #[derive(Component)] pub struct InConversationWithPlayer; #[derive(Component)] pub struct ActorEnteringVehicle; @@ -310,6 +313,8 @@ pub fn handle_vehicle_enter_exit( //player_actor.inside_entity = entity.index(); *vehicle_vis = Visibility::Hidden; driver_actor.v = vehicle_actor.v; + commands.entity(driver).remove::(); + commands.entity(vehicle).insert(PlayerCamera); commands.entity(vehicle).insert(PlayerDrivesThis); } } @@ -322,6 +327,8 @@ pub fn handle_vehicle_enter_exit( vehicle_actor.v = driver_actor.v; vehicle_actor.angular_momentum = driver_actor.angular_momentum; *vehicle_trans = driver_trans.clone(); + commands.entity(vehicle).remove::(); + commands.entity(driver).insert(PlayerCamera); commands.entity(vehicle).remove::(); } else { diff --git a/src/camera.rs b/src/camera.rs index 525b6d8..56f97aa 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,6 +1,7 @@ use bevy::prelude::*; use bevy::input::mouse::MouseMotion; use bevy::window::PrimaryWindow; +use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings}; use bevy_xpbd_3d::prelude::*; use std::f32::consts::*; use crate::{settings, audio, actor}; @@ -9,6 +10,9 @@ pub struct CameraControllerPlugin; impl Plugin for CameraControllerPlugin { fn build(&self, app: &mut App) { + app.add_systems(Startup, setup_camera); + app.add_systems(Update, handle_input); + app.add_systems(Update, manage_player_actor); app.add_systems(Update, run_camera_controller); } } @@ -39,6 +43,50 @@ impl Default for CameraController { } } +fn setup_camera( + mut commands: Commands, +) { + // Add player + commands.spawn(( + Camera3dBundle { + camera: Camera { + hdr: true, // HDR is required for bloom + ..default() + }, + transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }, + CameraController::default(), + BloomSettings { + composite_mode: BloomCompositeMode::EnergyConserving, + ..default() + }, + )); +} + +pub fn handle_input( + keyboard_input: Res>, + mut settings: ResMut, +) { + if keyboard_input.just_pressed(settings.key_camera) { + settings.third_person ^= true; + } +} + +fn manage_player_actor( + settings: Res, + mut q_playercam: Query<&mut Visibility, With> +) { + for mut vis in &mut q_playercam { + if settings.third_person { + *vis = Visibility::Inherited; + } + else { + *vis = Visibility::Hidden; + } + } +} + #[allow(clippy::too_many_arguments)] fn run_camera_controller( time: Res