mirror of
https://github.com/eliasstepanik/voxel-simulation.git
synced 2026-01-10 21:38:29 +00:00
Fixed Rotation and scale and rotation sync.
Moved Input To its own Plugin. Moved the camera to the Environment Plugin
This commit is contained in:
parent
9442befb27
commit
befbfb8935
@ -5,6 +5,7 @@ edition = "2024"
|
||||
description = "Horror-Game"
|
||||
repository = "https://github.com/eliasstepanik/horror-game"
|
||||
license = "MIT OR Apache-2.0"
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
[dependencies]
|
||||
@ -19,4 +20,8 @@ egui_dock = "0.14.0"
|
||||
spacetimedb-sdk = "1.0"
|
||||
hex = "0.4"
|
||||
random_word = { version = "0.5.0", features = ["en"] }
|
||||
rand = "0.8.5"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.8"
|
||||
|
||||
|
||||
|
||||
6
client/Config.toml
Normal file
6
client/Config.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[server]
|
||||
host = "http://100.85.241.101:3000"
|
||||
database = "network-game"
|
||||
|
||||
[movement]
|
||||
mode = "fligt"
|
||||
10
client/build.rs
Normal file
10
client/build.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = std::env::var("OUT_DIR").unwrap();
|
||||
let target_dir = Path::new(&out_dir).ancestors().nth(3).unwrap(); // gets target/debug or release
|
||||
|
||||
fs::copy("config.toml", target_dir.join("config.toml"))
|
||||
.expect("Failed to copy config.toml to target directory");
|
||||
}
|
||||
@ -24,12 +24,10 @@ impl Plugin for AppPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(UiState::new());
|
||||
app.insert_resource(InspectorVisible(true));
|
||||
|
||||
app.add_plugins(crate::plugins::camera::camera_plugin::CameraPlugin);
|
||||
app.add_plugins(crate::plugins::ui::ui_plugin::UiPlugin);
|
||||
app.add_plugins(crate::plugins::environment::environment_plugin::EnvironmentPlugin);
|
||||
app.add_plugins(crate::plugins::network::network_plugin::NetworkPlugin);
|
||||
|
||||
app.add_plugins(crate::plugins::input::input_plugin::InputPlugin);
|
||||
|
||||
app.add_systems(Update, (debug_gizmos, toggle_ui_system));
|
||||
app.add_systems(
|
||||
|
||||
15
client/src/config.rs
Normal file
15
client/src/config.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use bevy::prelude::Resource;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize, Resource)]
|
||||
pub struct Config {
|
||||
pub server: ServerConfig,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ServerConfig {
|
||||
pub host: String,
|
||||
pub database: String,
|
||||
|
||||
}
|
||||
12
client/src/helper/math.rs
Normal file
12
client/src/helper/math.rs
Normal file
@ -0,0 +1,12 @@
|
||||
pub trait RoundTo {
|
||||
/// Rounds `self` to `decimals` places.
|
||||
fn round_to(self, decimals: u32) -> f32;
|
||||
}
|
||||
|
||||
impl RoundTo for f32 {
|
||||
#[inline]
|
||||
fn round_to(self, decimals: u32) -> f32 {
|
||||
let factor = 10f32.powi(decimals as i32);
|
||||
(self * factor).round() / factor
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,4 @@
|
||||
pub mod debug_gizmos;
|
||||
pub mod egui_dock;
|
||||
pub mod vector_helper;
|
||||
pub mod math;
|
||||
|
||||
30
client/src/helper/vector_helper.rs
Normal file
30
client/src/helper/vector_helper.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use bevy::math::Vec3;
|
||||
use bevy::prelude::{Quat, Transform};
|
||||
use rand::Rng;
|
||||
use crate::helper::math::RoundTo;
|
||||
use crate::module_bindings::DbTransform;
|
||||
|
||||
pub(crate) fn random_vec3(min: f32, max: f32) -> Vec3 {
|
||||
let mut rng = rand::thread_rng();
|
||||
Vec3::new(
|
||||
rng.gen_range(min..max),
|
||||
rng.gen_range(min..max),
|
||||
rng.gen_range(min..max),
|
||||
)
|
||||
}
|
||||
|
||||
impl From<DbTransform> for Transform {
|
||||
fn from(db: DbTransform) -> Self {
|
||||
Transform {
|
||||
translation: Vec3::new(db.position.x, db.position.y, db.position.z),
|
||||
rotation: //Quat::from_xyzw(0.0, 0.0, 0.0, 0.0),
|
||||
Quat::from_xyzw(
|
||||
db.rotation.x.round_to(3),
|
||||
db.rotation.y.round_to(3),
|
||||
db.rotation.z.round_to(3),
|
||||
db.rotation.w.round_to(3),
|
||||
),
|
||||
scale: Vec3::new(db.scale.x.round_to(3), db.scale.y.round_to(3), db.scale.z.round_to(3)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,9 @@ mod app;
|
||||
mod helper;
|
||||
mod plugins;
|
||||
mod module_bindings;
|
||||
mod config;
|
||||
|
||||
use std::fs;
|
||||
use crate::app::AppPlugin;
|
||||
use bevy::gizmos::{AppGizmoBuilder, GizmoPlugin};
|
||||
use bevy::log::info;
|
||||
@ -13,6 +15,8 @@ use bevy::DefaultPlugins;
|
||||
use bevy_egui::EguiPlugin;
|
||||
use bevy_inspector_egui::DefaultInspectorConfigPlugin;
|
||||
use bevy_window::{PresentMode, Window, WindowPlugin};
|
||||
use toml;
|
||||
use crate::config::Config;
|
||||
|
||||
const TITLE: &str = "horror-game";
|
||||
const RESOLUTION: (f32, f32) = (1920f32, 1080f32);
|
||||
@ -21,13 +25,27 @@ const DECORATIONS: bool = true;
|
||||
const TRANSPARENT: bool = true;
|
||||
const PRESENT_MODE: PresentMode = PresentMode::AutoVsync;
|
||||
|
||||
|
||||
|
||||
fn main() {
|
||||
let config_str = fs::read_to_string("Config.toml").expect("Failed to read config file");
|
||||
let config: Config = toml::from_str(&config_str).expect("Failed to parse config");
|
||||
|
||||
|
||||
|
||||
|
||||
let mut app = App::new();
|
||||
|
||||
app.insert_resource(config);
|
||||
|
||||
register_platform_plugins(&mut app);
|
||||
|
||||
app.add_plugins(AppPlugin);
|
||||
app.add_plugins(EguiPlugin);
|
||||
app.add_plugins(DefaultInspectorConfigPlugin);
|
||||
|
||||
|
||||
|
||||
/*app.add_plugins(GizmoPlugin);*/
|
||||
|
||||
app.run();
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
use bevy::a11y::AccessibilitySystem::Update;
|
||||
use bevy::app::{App, Plugin, PreUpdate, Startup};
|
||||
|
||||
pub struct CameraPlugin;
|
||||
impl Plugin for CameraPlugin {
|
||||
fn build(&self, _app: &mut App) {
|
||||
_app.add_systems(
|
||||
Startup,
|
||||
(crate::plugins::camera::systems::camera_system::setup),
|
||||
);
|
||||
_app.add_systems(
|
||||
PreUpdate,
|
||||
(crate::plugins::camera::systems::camera_system::camera_controller_system),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,2 +0,0 @@
|
||||
pub mod camera_plugin;
|
||||
pub mod systems;
|
||||
@ -1 +0,0 @@
|
||||
pub mod camera_system;
|
||||
@ -1,6 +1,11 @@
|
||||
use bevy::app::{App, Plugin};
|
||||
use bevy::app::{App, Plugin, PreStartup, PreUpdate, Startup};
|
||||
pub struct EnvironmentPlugin;
|
||||
impl Plugin for EnvironmentPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
|
||||
app.add_systems(
|
||||
Startup,
|
||||
(crate::plugins::environment::systems::camera_system::setup),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
53
client/src/plugins/environment/systems/camera_system.rs
Normal file
53
client/src/plugins/environment/systems/camera_system.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use crate::helper::egui_dock::MainCamera;
|
||||
use bevy::input::mouse::{MouseMotion, MouseWheel};
|
||||
use bevy::math::Vec3;
|
||||
use bevy::prelude::*;
|
||||
use bevy_render::camera::{Exposure, PhysicalCameraParameters, Projection};
|
||||
use bevy_window::CursorGrabMode;
|
||||
use rand::Rng;
|
||||
use random_word::Lang;
|
||||
use crate::module_bindings::{set_name, set_position, spawn_entity, DbTransform, DbVector3, DbVector4};
|
||||
use crate::plugins::network::systems::database::DbConnectionResource;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct CameraController {
|
||||
pub yaw: f32,
|
||||
pub pitch: f32,
|
||||
pub speed: f32,
|
||||
pub sensitivity: f32,
|
||||
}
|
||||
|
||||
impl Default for CameraController {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
yaw: 0.0,
|
||||
pitch: 0.0,
|
||||
speed: 10.0,
|
||||
sensitivity: 0.1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup(mut commands: Commands,) {
|
||||
|
||||
|
||||
commands.spawn((
|
||||
Transform::from_xyz(0.0, 0.0, 10.0), // initial f32
|
||||
GlobalTransform::default(),
|
||||
Camera3d::default(),
|
||||
Projection::from(PerspectiveProjection {
|
||||
near: 0.0001,
|
||||
..default()
|
||||
}),
|
||||
MainCamera,
|
||||
CameraController::default(),
|
||||
Exposure::from_physical_camera(PhysicalCameraParameters {
|
||||
aperture_f_stops: 1.0,
|
||||
shutter_speed_s: 1.0 / 125.0,
|
||||
sensitivity_iso: 100.0,
|
||||
sensor_height: 0.01866,
|
||||
}),
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
@ -1 +1,2 @@
|
||||
pub mod environment_system;
|
||||
pub mod camera_system;
|
||||
|
||||
20
client/src/plugins/input/input_plugin.rs
Normal file
20
client/src/plugins/input/input_plugin.rs
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
use bevy::app::{App, Plugin, PreUpdate, Startup};
|
||||
use bevy::prelude::{IntoSystemConfigs, Update};
|
||||
|
||||
pub struct InputPlugin;
|
||||
impl Plugin for InputPlugin {
|
||||
fn build(&self, _app: &mut App) {
|
||||
_app.add_systems(
|
||||
Update,
|
||||
(
|
||||
crate::plugins::input::systems::console::console_system,
|
||||
crate::plugins::input::systems::flight::flight_systems,
|
||||
crate::plugins::input::systems::ui::ui_system,
|
||||
crate::plugins::input::systems::network::network_system,
|
||||
crate::plugins::input::systems::movement::movement_system,
|
||||
),
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
2
client/src/plugins/input/mod.rs
Normal file
2
client/src/plugins/input/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod systems;
|
||||
pub mod input_plugin;
|
||||
23
client/src/plugins/input/systems/console.rs
Normal file
23
client/src/plugins/input/systems/console.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use bevy::app::AppExit;
|
||||
use bevy::input::ButtonInput;
|
||||
use bevy::input::mouse::{MouseMotion, MouseWheel};
|
||||
use bevy::prelude::{EventReader, EventWriter, KeyCode, Query, Res, ResMut, Time, Transform};
|
||||
use bevy_window::Window;
|
||||
use crate::plugins::environment::systems::camera_system::CameraController;
|
||||
use crate::plugins::network::systems::database::DbConnectionResource;
|
||||
|
||||
pub fn console_system(
|
||||
time: Res<Time>,
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>, /*
|
||||
mouse_button_input: Res<ButtonInput<MouseButton>>,*/
|
||||
mut mouse_motion_events: EventReader<MouseMotion>,
|
||||
mut mouse_wheel_events: EventReader<MouseWheel>,
|
||||
mut windows: Query<&mut Window>,
|
||||
mut query: Query<(&mut Transform, &mut CameraController)>,
|
||||
mut app_exit_events: EventWriter<AppExit>,
|
||||
mut ctx: ResMut<DbConnectionResource>,
|
||||
) {
|
||||
let mut window = windows.single_mut();
|
||||
let (mut transform, mut controller) = query.single_mut();
|
||||
|
||||
}
|
||||
@ -1,68 +1,16 @@
|
||||
use crate::helper::egui_dock::MainCamera;
|
||||
use bevy::app::AppExit;
|
||||
use bevy::input::ButtonInput;
|
||||
use bevy::input::mouse::{MouseMotion, MouseWheel};
|
||||
use bevy::math::Vec3;
|
||||
use bevy::prelude::*;
|
||||
use bevy_render::camera::{Exposure, PhysicalCameraParameters, Projection};
|
||||
use bevy_window::CursorGrabMode;
|
||||
use rand::Rng;
|
||||
use bevy::math::{Quat, Vec3};
|
||||
use bevy::prelude::{EventReader, EventWriter, KeyCode, Query, Res, ResMut, Time, Transform};
|
||||
use bevy_window::{CursorGrabMode, Window};
|
||||
use random_word::Lang;
|
||||
use crate::module_bindings::{set_name, set_position, spawn_entity, DbTransform, DbVector3, DbVector4};
|
||||
use crate::plugins::environment::systems::camera_system::CameraController;
|
||||
use crate::plugins::network::systems::database::DbConnectionResource;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct CameraController {
|
||||
pub yaw: f32,
|
||||
pub pitch: f32,
|
||||
pub speed: f32,
|
||||
pub sensitivity: f32,
|
||||
}
|
||||
|
||||
impl Default for CameraController {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
yaw: 0.0,
|
||||
pitch: 0.0,
|
||||
speed: 10.0,
|
||||
sensitivity: 0.1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup(mut commands: Commands,
|
||||
db_resource: Res<DbConnectionResource>,) {
|
||||
|
||||
|
||||
commands.spawn((
|
||||
Transform::from_xyz(0.0, 0.0, 10.0), // initial f32
|
||||
GlobalTransform::default(),
|
||||
Camera3d::default(),
|
||||
Projection::from(PerspectiveProjection {
|
||||
near: 0.0001,
|
||||
..default()
|
||||
}),
|
||||
MainCamera,
|
||||
CameraController::default(),
|
||||
Exposure::from_physical_camera(PhysicalCameraParameters {
|
||||
aperture_f_stops: 1.0,
|
||||
shutter_speed_s: 1.0 / 125.0,
|
||||
sensitivity_iso: 100.0,
|
||||
sensor_height: 0.01866,
|
||||
}),
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
fn random_vec3(min: f32, max: f32) -> Vec3 {
|
||||
let mut rng = rand::thread_rng();
|
||||
Vec3::new(
|
||||
rng.gen_range(min..max),
|
||||
rng.gen_range(min..max),
|
||||
rng.gen_range(min..max),
|
||||
)
|
||||
}
|
||||
|
||||
/// Example system to control a camera using double-precision for position.
|
||||
pub fn camera_controller_system(
|
||||
/// Example system to input a camera using double-precision for position.
|
||||
pub fn flight_systems(
|
||||
time: Res<Time>,
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>, /*
|
||||
mouse_button_input: Res<ButtonInput<MouseButton>>,*/
|
||||
@ -110,34 +58,6 @@ pub fn camera_controller_system(
|
||||
}
|
||||
}
|
||||
|
||||
let word = random_word::get(Lang::En);
|
||||
|
||||
if keyboard_input.just_pressed(KeyCode::KeyQ) {
|
||||
ctx.0.reducers.set_name(word.to_string()).unwrap();
|
||||
}
|
||||
if keyboard_input.just_pressed(KeyCode::KeyE) {
|
||||
let rand_position = random_vec3(-10.0,10.0);
|
||||
let rand_rotation = random_vec3(-10.0,10.0);
|
||||
let rand_scale = random_vec3(0.1,1.0);
|
||||
ctx.0.reducers.spawn_entity(DbTransform{
|
||||
position: DbVector3{
|
||||
x: rand_position.x,
|
||||
y: rand_position.y,
|
||||
z: rand_position.z,
|
||||
},
|
||||
rotation: DbVector4 {
|
||||
x: rand_rotation.x,
|
||||
y: rand_rotation.y,
|
||||
z: rand_position.z,
|
||||
w: 0.0,
|
||||
},
|
||||
scale: DbVector3 {
|
||||
x: rand_scale.x,
|
||||
y: rand_scale.x,
|
||||
z: rand_scale.x,
|
||||
},
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
// ====================
|
||||
// 3) Handle Keyboard Movement (WASD, Space, Shift)
|
||||
@ -183,30 +103,7 @@ pub fn camera_controller_system(
|
||||
y: transform.translation.y,
|
||||
z: transform.translation.z,
|
||||
}).expect("TODO: panic message");
|
||||
|
||||
|
||||
|
||||
|
||||
// =========================
|
||||
// 4) Lock/Unlock Mouse (L)
|
||||
// =========================
|
||||
if keyboard_input.just_pressed(KeyCode::KeyL) {
|
||||
// Toggle between locked and unlocked
|
||||
if window.cursor_options.grab_mode == CursorGrabMode::None {
|
||||
// Lock
|
||||
window.cursor_options.visible = false;
|
||||
window.cursor_options.grab_mode = CursorGrabMode::Locked;
|
||||
} else {
|
||||
// Unlock
|
||||
window.cursor_options.visible = true;
|
||||
window.cursor_options.grab_mode = CursorGrabMode::None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =======================
|
||||
// 7) Exit on Escape
|
||||
// =======================
|
||||
if keyboard_input.pressed(KeyCode::Escape) {
|
||||
app_exit_events.send(Default::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
5
client/src/plugins/input/systems/mod.rs
Normal file
5
client/src/plugins/input/systems/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub mod movement;
|
||||
pub mod flight;
|
||||
pub mod console;
|
||||
pub mod ui;
|
||||
pub mod network;
|
||||
22
client/src/plugins/input/systems/movement.rs
Normal file
22
client/src/plugins/input/systems/movement.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use bevy::app::AppExit;
|
||||
use bevy::input::ButtonInput;
|
||||
use bevy::input::mouse::{MouseMotion, MouseWheel};
|
||||
use bevy::prelude::{EventReader, EventWriter, KeyCode, Query, Res, ResMut, Time, Transform};
|
||||
use bevy_window::Window;
|
||||
use crate::plugins::environment::systems::camera_system::CameraController;
|
||||
use crate::plugins::network::systems::database::DbConnectionResource;
|
||||
|
||||
|
||||
///TODO
|
||||
pub fn movement_system(
|
||||
time: Res<Time>,
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>, /*
|
||||
mouse_button_input: Res<ButtonInput<MouseButton>>,*/
|
||||
mut mouse_motion_events: EventReader<MouseMotion>,
|
||||
mut mouse_wheel_events: EventReader<MouseWheel>,
|
||||
mut windows: Query<&mut Window>,
|
||||
mut query: Query<(&mut Transform, &mut CameraController)>,
|
||||
mut app_exit_events: EventWriter<AppExit>,
|
||||
mut ctx: ResMut<DbConnectionResource>,
|
||||
) {
|
||||
}
|
||||
47
client/src/plugins/input/systems/network.rs
Normal file
47
client/src/plugins/input/systems/network.rs
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
use bevy::input::ButtonInput;
|
||||
use bevy::math::{EulerRot, Quat};
|
||||
use bevy::prelude::{KeyCode, Res, ResMut,};
|
||||
use random_word::Lang;
|
||||
use crate::module_bindings::{set_name, spawn_entity, DbTransform, DbVector3, DbVector4};
|
||||
use crate::plugins::network::systems::database::DbConnectionResource;
|
||||
|
||||
pub fn network_system(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
ctx: ResMut<DbConnectionResource>,
|
||||
) {
|
||||
let word = random_word::get(Lang::En);
|
||||
|
||||
if keyboard_input.just_pressed(KeyCode::KeyQ) {
|
||||
ctx.0.reducers.set_name(word.to_string()).unwrap();
|
||||
}
|
||||
if keyboard_input.just_pressed(KeyCode::KeyE) {
|
||||
let rand_position = crate::helper::vector_helper::random_vec3(-10.0, 10.0);
|
||||
let rand_rotation = crate::helper::vector_helper::random_vec3(0.0, 10.0);
|
||||
let rand_rotation = Quat::from_euler(EulerRot::XYZ,rand_rotation.x,rand_rotation.y,rand_rotation.z).normalize();
|
||||
let rand_scale = crate::helper::vector_helper::random_vec3(0.1, 1.0);
|
||||
ctx.0.reducers.spawn_entity(DbTransform{
|
||||
position: DbVector3{
|
||||
x: rand_position.x,
|
||||
y: rand_position.y,
|
||||
z: rand_position.z,
|
||||
},
|
||||
rotation: DbVector4 {
|
||||
x: rand_rotation.x,
|
||||
y: rand_rotation.y,
|
||||
z: rand_rotation.z,
|
||||
w: rand_rotation.w,
|
||||
},
|
||||
|
||||
|
||||
|
||||
scale: DbVector3 {
|
||||
x: rand_scale.x,
|
||||
y: rand_scale.x,
|
||||
z: rand_scale.x,
|
||||
},
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
29
client/src/plugins/input/systems/ui.rs
Normal file
29
client/src/plugins/input/systems/ui.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use bevy::app::AppExit;
|
||||
use bevy::input::ButtonInput;
|
||||
use bevy::prelude::{EventWriter, KeyCode, Query, Res,};
|
||||
use bevy_window::{CursorGrabMode, Window};
|
||||
|
||||
pub fn ui_system(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
mut app_exit_events: EventWriter<AppExit>,
|
||||
mut windows: Query<&mut Window>,
|
||||
) {
|
||||
let mut window = windows.single_mut();
|
||||
|
||||
if keyboard_input.just_pressed(KeyCode::KeyL) {
|
||||
// Toggle between locked and unlocked
|
||||
if window.cursor_options.grab_mode == CursorGrabMode::None {
|
||||
// Lock
|
||||
window.cursor_options.visible = false;
|
||||
window.cursor_options.grab_mode = CursorGrabMode::Locked;
|
||||
} else {
|
||||
// Unlock
|
||||
window.cursor_options.visible = true;
|
||||
window.cursor_options.grab_mode = CursorGrabMode::None;
|
||||
}
|
||||
}
|
||||
|
||||
if keyboard_input.pressed(KeyCode::Escape) {
|
||||
app_exit_events.send(Default::default());
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
pub mod camera;
|
||||
|
||||
pub mod environment;
|
||||
pub mod ui;
|
||||
pub mod network;
|
||||
pub mod input;
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ pub struct NetworkPlugin;
|
||||
impl Plugin for NetworkPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(PreStartup, setup_database);
|
||||
app.add_systems(Startup, init);
|
||||
app.add_systems(Update, sync_entities_system);
|
||||
app.add_systems(PostUpdate, sync_entities_system);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use std::fmt::Debug;
|
||||
use std::ops::Deref;
|
||||
use bevy::ecs::system::SystemState;
|
||||
use bevy::prelude::{Commands, Resource, World};
|
||||
use bevy::prelude::{Commands, DetectChanges, Mut, Res, ResMut, Resource, World};
|
||||
use bevy::utils::info;
|
||||
use spacetimedb_sdk::{credentials, DbContext, Error, Event, Identity, Status, Table, TableWithPrimaryKey};
|
||||
use crate::config::ServerConfig;
|
||||
use crate::module_bindings::*;
|
||||
use crate::plugins::network::systems::callbacks::*;
|
||||
use crate::plugins::network::systems::connection::*;
|
||||
@ -16,9 +19,9 @@ const DB_NAME: &str = "network-game";
|
||||
#[derive(Resource)]
|
||||
pub struct DbConnectionResource(pub(crate) DbConnection);
|
||||
|
||||
pub fn setup_database(mut commands: Commands) {
|
||||
pub fn setup_database(mut commands: Commands, config: Res<crate::Config>) {
|
||||
// Call your connection function and insert the connection as a resource.
|
||||
let ctx = connect_to_db();
|
||||
let ctx = connect_to_db(config);
|
||||
register_callbacks(&ctx);
|
||||
subscribe_to_tables(&ctx);
|
||||
ctx.run_threaded();
|
||||
@ -30,13 +33,16 @@ pub fn setup_database(mut commands: Commands) {
|
||||
|
||||
/// Register subscriptions for all rows of both tables
|
||||
|
||||
fn connect_to_db() -> DbConnection {
|
||||
fn connect_to_db(config: Res<crate::Config>) -> DbConnection {
|
||||
|
||||
println!("It's there: {:?}", &config.server);
|
||||
|
||||
DbConnection::builder()
|
||||
.on_connect(on_connected)
|
||||
.on_connect_error(on_connect_error)
|
||||
.on_disconnect( on_disconnected)
|
||||
.with_module_name(DB_NAME)
|
||||
.with_uri(HOST)
|
||||
.with_module_name(&config.server.database)
|
||||
.with_uri(&config.server.host)
|
||||
.build()
|
||||
.expect("Failed to connect")
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
use std::collections::HashSet;
|
||||
use bevy::math::Vec3;
|
||||
use bevy::log::debug;
|
||||
use bevy::math::{NormedVectorSpace, Vec3};
|
||||
use bevy::pbr::{MeshMaterial3d, StandardMaterial};
|
||||
use bevy::prelude::{default, Bundle, Commands, Component, Cuboid, DespawnRecursiveExt, Entity, GlobalTransform, Mesh, Quat, Query, Res, ResMut, Sphere, Transform};
|
||||
use bevy::prelude::{default, info, Bundle, Commands, Component, Cuboid, DespawnRecursiveExt, DetectChangesMut, Entity, GlobalTransform, Mesh, PbrBundle, Quat, Query, Res, ResMut, Sphere, Transform, TransformBundle};
|
||||
use bevy_asset::Assets;
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_render::mesh::Mesh3d;
|
||||
use spacetimedb_sdk::Table;
|
||||
use crate::helper::math::RoundTo;
|
||||
use crate::module_bindings::{DbTransform, DbVector3, EntityTableAccess, EntityType};
|
||||
use crate::plugins::network::systems::database::DbConnectionResource;
|
||||
|
||||
@ -18,35 +20,18 @@ pub struct EntityDto {
|
||||
pub transform: DbTransform,
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn init(mut commands: Commands,
|
||||
ctx: Res<DbConnectionResource>,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,) {
|
||||
|
||||
|
||||
|
||||
let debug_material = materials.add(StandardMaterial { ..default() });
|
||||
|
||||
for entity in ctx.0.db.entity().iter() {
|
||||
commands.spawn((
|
||||
Mesh3d(meshes.add(Cuboid::default()),),
|
||||
MeshMaterial3d(debug_material.clone ()),
|
||||
db_transfrom_to_transfrom(entity.transform.clone()),
|
||||
EntityDto{
|
||||
entity_id: entity.entity_id,
|
||||
transform: entity.transform
|
||||
}
|
||||
));
|
||||
|
||||
impl From<crate::module_bindings::Entity> for EntityDto {
|
||||
fn from(e: crate::module_bindings::Entity) -> Self {
|
||||
EntityDto {
|
||||
entity_id: e.entity_id,
|
||||
transform: e.transform,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// System that syncs DB entities with the Bevy ECS
|
||||
pub fn sync_entities_system(
|
||||
mut commands: Commands,
|
||||
@ -54,7 +39,7 @@ pub fn sync_entities_system(
|
||||
|
||||
// We need the Entity handle for potential despawning,
|
||||
// plus mutable references if we want to update Transform/EntityDto
|
||||
mut query: Query<(Entity, &mut Transform, &mut EntityDto)>,
|
||||
mut query: Query<(Entity, &mut Transform, &mut GlobalTransform, &mut EntityDto)>,
|
||||
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
@ -67,16 +52,20 @@ pub fn sync_entities_system(
|
||||
for db_entity in db_entities.iter() {
|
||||
|
||||
// Try to find a matching ECS entity by entity_id
|
||||
if let Some((_, mut transform, mut dto)) =
|
||||
query.iter_mut().find(|(_, _, dto)| dto.entity_id == db_entity.entity_id)
|
||||
if let Some((_, mut transform, mut global, mut dto)) =
|
||||
query.iter_mut().find(|(_, _, _, dto)| dto.entity_id == db_entity.entity_id)
|
||||
{
|
||||
// Update fields
|
||||
dto.transform.position = db_entity.transform.position.clone();
|
||||
transform.translation = Vec3::new(
|
||||
db_entity.transform.position.x,
|
||||
db_entity.transform.position.y,
|
||||
db_entity.transform.position.z,
|
||||
);
|
||||
|
||||
// build the new local Transform
|
||||
let new_tf = Transform::from(db_entity.transform.clone());
|
||||
|
||||
// overwrite both components
|
||||
*transform = new_tf;
|
||||
*global = GlobalTransform::from(new_tf);
|
||||
|
||||
// keep your DTO in sync
|
||||
dto.transform = db_entity.transform.clone();
|
||||
|
||||
} else {
|
||||
// Not found in ECS, so spawn a new entity
|
||||
@ -92,46 +81,25 @@ pub fn sync_entities_system(
|
||||
EntityType::Custom => todo!(),
|
||||
};
|
||||
|
||||
let new_tf = Transform::from(db_entity.transform.clone());
|
||||
|
||||
commands.spawn((
|
||||
db_transfrom_to_transfrom(db_entity.transform.clone()),
|
||||
GlobalTransform::default(),
|
||||
TransformBundle::from_transform(new_tf), // inserts BOTH Transform and GlobalTransform
|
||||
entity_type,
|
||||
MeshMaterial3d(debug_material),
|
||||
EntityDto {
|
||||
entity_id: db_entity.entity_id,
|
||||
transform: db_entity.transform.clone(),
|
||||
},
|
||||
EntityDto::from(db_entity.clone()),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// --- 3) Despawn any ECS entity that doesn't exist in the DB anymore ---
|
||||
for (entity, _, dto) in query.iter_mut() {
|
||||
for (entity,_, _, dto) in query.iter_mut() {
|
||||
if !db_ids.contains(&dto.entity_id) {
|
||||
// This ECS entity no longer matches anything in the DB => remove it
|
||||
commands.entity(entity).despawn_recursive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn db_transfrom_to_transfrom(db_transform: DbTransform) -> Transform{
|
||||
Transform::from_xyz(
|
||||
db_transform.position.x,
|
||||
db_transform.position.y,
|
||||
db_transform.position.z,
|
||||
).with_rotation(
|
||||
Quat::from_xyzw(
|
||||
db_transform.rotation.x,
|
||||
db_transform.rotation.y,
|
||||
db_transform.rotation.z,
|
||||
db_transform.rotation.w
|
||||
)
|
||||
).with_scale(
|
||||
Vec3::new(
|
||||
db_transform.scale.x,
|
||||
db_transform.scale.y,
|
||||
db_transform.scale.z,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::plugins::camera::systems::camera_system::CameraController;
|
||||
use crate::plugins::environment::systems::camera_system::CameraController;
|
||||
use bevy::asset::AssetServer;
|
||||
use bevy::prelude::*;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user