A multiplayer VR framework w/voice chat
at main 4.6 kB view raw
1use std::f32::consts::PI; 2 3use bevy::{ input::mouse::MouseMotion, prelude::* }; 4use bevy_mod_openxr::{helper_traits::ToQuat, resources::OxrViews}; 5use bevy_mod_xr::session::{XrState, XrTrackingRoot}; 6use felix_audio::voice::microphone::VoiceChatMicrophone; 7 8use crate::net::connection::Connection; 9 10#[derive(Component)] 11pub struct DebugCamera{ 12 pitch: f32, 13 yaw: f32 14} 15 16impl Default for DebugCamera{ 17 fn default() -> Self { 18 Self { 19 pitch: 0.0, 20 yaw: -PI / 2.0 21 } 22 } 23} 24 25pub fn vr_locomotion( // TODO: Move locomotion to controllers instead of keyboard 26 views: ResMut<OxrViews>, 27 mut position_query: Query<&mut Transform, With<XrTrackingRoot>>, 28 keys: Res<ButtonInput<KeyCode>>, 29 xr_state: Res<XrState>, 30 time: Res<Time> 31){ 32 if *xr_state == XrState::Running{ 33 let mut delta_time = time.delta_secs(); 34 if keys.pressed(KeyCode::ShiftLeft){ delta_time *= 2.0; } 35 36 let mut transform = position_query.single_mut().unwrap(); 37 let view = views.first().unwrap(); 38 39 let cam = view.pose.orientation.to_quat(); 40 41 if keys.pressed(KeyCode::KeyW){ 42 let mut dir = cam * -Vec3::Z * delta_time; 43 dir.y = 0.0; 44 45 transform.translation += dir; 46 } else if keys.pressed(KeyCode::KeyS){ 47 let mut dir = cam * Vec3::Z * delta_time; 48 dir.y = 0.0; 49 50 transform.translation += dir; 51 } 52 53 if keys.pressed(KeyCode::KeyA){ 54 let mut dir = cam * -Vec3::X * delta_time; 55 dir.y = 0.0; 56 57 transform.translation += dir; 58 } else if keys.pressed(KeyCode::KeyD){ 59 let mut dir = cam * Vec3::X * delta_time; 60 dir.y = 0.0; 61 62 transform.translation += dir; 63 } 64 } 65} 66 67pub fn update( 68 mut query: Query<(&mut DebugCamera, &mut Transform)>, 69 time: Res<Time>, 70 71 keys: Res<ButtonInput<KeyCode>>, 72 mouse_buttons: Res<ButtonInput<MouseButton>>, 73 mut mouse_motion: MessageReader<MouseMotion>, 74 75 // Debug Text 76 mut debug_text: Query<(&mut Text, &DebugText)>, 77 voice: Query<&VoiceChatMicrophone>, 78 networking: Query<&Connection>, 79 xr_state: Res<XrState> 80){ 81 let net_manager = networking.single().unwrap(); 82 let xr_state = xr_state.into_inner(); 83 84 let ( mut debug, mut transform ) = query.single_mut().unwrap(); 85 86 if *xr_state != XrState::Running{ 87 let mut delta_time = time.delta_secs(); 88 if keys.pressed(KeyCode::ShiftLeft){ delta_time *= 2.0; } 89 90 for ev in mouse_motion.read(){ 91 if mouse_buttons.pressed(MouseButton::Right){ 92 debug.pitch -= ev.delta.y * delta_time * 0.1; 93 debug.yaw -= ev.delta.x * delta_time * 0.1; 94 } 95 } 96 97 transform.rotation = Quat::from_euler(EulerRot::YXZ, debug.yaw, debug.pitch, 0.0); 98 99 if keys.pressed(KeyCode::KeyW){ 100 let dir = transform.forward(); 101 transform.translation += dir * delta_time; 102 } else if keys.pressed(KeyCode::KeyS){ 103 let dir = -transform.forward(); 104 transform.translation += dir * delta_time; 105 } 106 107 if keys.pressed(KeyCode::KeyA){ 108 let dir = transform.left(); 109 transform.translation += dir * delta_time; 110 } else if keys.pressed(KeyCode::KeyD){ 111 let dir = -transform.left(); 112 transform.translation += dir * delta_time; 113 } 114 115 if keys.pressed(KeyCode::KeyE){ 116 let dir = transform.up(); 117 transform.translation += dir * delta_time; 118 } else if keys.pressed(KeyCode::KeyQ){ 119 let dir = -transform.up(); 120 transform.translation += dir * delta_time; 121 } 122 } 123 124 let mut remote_rms = "".to_owned(); 125 for id in net_manager.get_remote_player_voice_ids(){ 126 remote_rms += format!( 127 "{}: {:.4}db\n", 128 id, 129 net_manager.get_remote_player_voice_rms(&id) 130 ).as_str(); 131 } 132 133 let ( rms, mic_open ) = if let Ok(mic) = voice.single(){ 134 mic.get_rms_of_last_packet() 135 } else{ 136 ( -1.0, false ) 137 }; 138 139 let ( mut text, _ ) = debug_text.single_mut().unwrap(); 140 text.0 = format!( 141"Microphone RMS: {:.4}db Open: {} 142{}Position: X: {:.2} Y: {:.2} Z: {:.2} 143Rotation: X: {:.2} Y: {:.2} Z: {:.2} W: {:.2} 144XR State: {:#?}", 145 rms, 146 mic_open, 147 148 remote_rms, 149 150 transform.translation.x, 151 transform.translation.y, 152 transform.translation.z, 153 154 transform.rotation.x, 155 transform.rotation.y, 156 transform.rotation.z, 157 transform.rotation.w, 158 159 xr_state 160 ); 161} 162 163#[derive(Component)] 164pub struct DebugText; 165 166pub fn setup( 167 mut commands: Commands 168){ 169 commands.spawn(( 170 Node { 171 position_type: PositionType::Absolute, 172 bottom: px(5.0), 173 right: px(5.0), 174 ..default() 175 }, 176 Text::new("Here is some text"), 177 TextColor(Color::WHITE), 178 TextLayout::new_with_justify(Justify::Right), 179 DebugText 180 )); 181}