From 3770dcd3951ecb086762e70b576447f96b8d0d65 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Fri, 13 Dec 2024 18:48:02 +0200 Subject: [PATCH] feat(floor): create floor module --- src/dev_tools/ui/maze_controls.rs | 30 ++++++++--- src/floor/components.rs | 19 +++++++ src/floor/mod.rs | 5 ++ src/lib.rs | 5 +- src/maze/assets.rs | 13 +++-- src/maze/components.rs | 82 +++++++++++++++++++++++++++-- src/maze/errors.rs | 10 ++++ src/maze/events.rs | 4 +- src/maze/mod.rs | 7 +-- src/maze/resources.rs | 86 ++++--------------------------- src/maze/systems/despawn.rs | 2 +- src/maze/systems/recreation.rs | 18 +++++-- src/maze/systems/setup.rs | 13 +++-- src/maze/systems/spawn.rs | 44 ++++++++++------ src/player/systems/input.rs | 11 ++-- src/player/systems/movement.rs | 6 ++- src/player/systems/respawn.rs | 19 +++++-- src/player/systems/setup.rs | 17 ++++-- src/player/systems/spawn.rs | 13 ++--- 19 files changed, 256 insertions(+), 148 deletions(-) create mode 100644 src/floor/components.rs create mode 100644 src/floor/mod.rs create mode 100644 src/maze/errors.rs diff --git a/src/dev_tools/ui/maze_controls.rs b/src/dev_tools/ui/maze_controls.rs index f611a2c..be5bf2f 100644 --- a/src/dev_tools/ui/maze_controls.rs +++ b/src/dev_tools/ui/maze_controls.rs @@ -1,5 +1,6 @@ use crate::{ - maze::{events::RecreateMazeEvent, MazeConfig, MazePluginLoaded}, + floor::components::{CurrentFloor, Floor}, + maze::{components::MazeConfig, events::RecreateMazeEvent, GlobalMazeConfig, MazePluginLoaded}, player::events::RespawnPlayer, }; use bevy::{prelude::*, window::PrimaryWindow}; @@ -22,11 +23,18 @@ pub(crate) fn maze_controls_ui(world: &mut World) { else { return; }; - let mut egui_context = egui_context.clone(); + let Ok((mut maze_config, floor)) = world + .query_filtered::<(&mut MazeConfig, &Floor), With>() + .get_single(world) + else { + return; + }; + let mut maze_config = (*maze_config).clone(); + egui::Window::new("Maze Controls").show(egui_context.get_mut(), |ui| { - if let Some(mut maze_config) = world.get_resource_mut::() { + if let Some(mut global_config) = world.get_resource_mut::() { let mut changed = false; ui.heading("Maze Configuration"); @@ -34,11 +42,11 @@ pub(crate) fn maze_controls_ui(world: &mut World) { changed |= add_drag_value_control(ui, "Radius:", &mut maze_config.radius, 1.0, 1..=100); changed |= - add_drag_value_control(ui, "Height:", &mut maze_config.height, 0.5, 1.0..=50.0); + add_drag_value_control(ui, "Height:", &mut global_config.height, 0.5, 1.0..=50.0); changed |= add_drag_value_control( ui, "Hex Size:", - &mut maze_config.hex_size, + &mut global_config.hex_size, 1.0, 1.0..=100.0, ); @@ -50,11 +58,19 @@ pub(crate) fn maze_controls_ui(world: &mut World) { // Trigger recreation if any value changed if changed { - maze_config.update(); + maze_config.update(&global_config); + + if let Ok(mut actual_maze_config) = world + .query_filtered::<&mut MazeConfig, With>() + .get_single_mut(world) + { + *actual_maze_config = maze_config; + } + if let Some(mut event_writer) = world.get_resource_mut::>() { - event_writer.send(RecreateMazeEvent { floor: 1 }); + event_writer.send(RecreateMazeEvent { floor: floor.0 }); } if let Some(mut event_writer) = world.get_resource_mut::>() { event_writer.send(RespawnPlayer); diff --git a/src/floor/components.rs b/src/floor/components.rs new file mode 100644 index 0000000..de73815 --- /dev/null +++ b/src/floor/components.rs @@ -0,0 +1,19 @@ +use bevy::prelude::*; + +#[derive(Debug, Reflect, Component)] +#[reflect(Component)] +pub struct Floor(pub u8); + +#[derive(Debug, Reflect, Component)] +#[reflect(Component)] +pub struct TargetFloor(pub u8); + +#[derive(Debug, Reflect, Component)] +#[reflect(Component)] +pub struct CurrentFloor; + +impl Default for Floor { + fn default() -> Self { + Self(1) + } +} diff --git a/src/floor/mod.rs b/src/floor/mod.rs new file mode 100644 index 0000000..3f632c7 --- /dev/null +++ b/src/floor/mod.rs @@ -0,0 +1,5 @@ +use bevy::prelude::*; + +pub mod components; + +pub(super) fn plugin(app: &mut App) {} diff --git a/src/lib.rs b/src/lib.rs index 2ca0c9e..98a0536 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,9 @@ mod asset_tracking; pub mod audio; #[cfg(feature = "dev")] mod dev_tools; -mod maze; -mod player; +pub mod floor; +pub mod maze; +pub mod player; mod screens; pub mod theme; diff --git a/src/maze/assets.rs b/src/maze/assets.rs index 9d56b1f..011d406 100644 --- a/src/maze/assets.rs +++ b/src/maze/assets.rs @@ -1,4 +1,4 @@ -use super::MazeConfig; +use super::resources::GlobalMazeConfig; use bevy::prelude::*; use std::f32::consts::FRAC_PI_2; @@ -17,13 +17,16 @@ impl MazeAssets { pub(crate) fn new( meshes: &mut ResMut>, materials: &mut ResMut>, - config: &MazeConfig, + global_config: &GlobalMazeConfig, ) -> MazeAssets { MazeAssets { - hex_mesh: meshes.add(generate_hex_mesh(config.hex_size, config.height)), + hex_mesh: meshes.add(generate_hex_mesh( + global_config.hex_size, + global_config.height, + )), wall_mesh: meshes.add(generate_square_mesh( - config.hex_size + config.wall_size() / WALL_OVERLAP_MODIFIER, - config.wall_size(), + global_config.hex_size + global_config.wall_size() / WALL_OVERLAP_MODIFIER, + global_config.wall_size(), )), hex_material: materials.add(white_material()), wall_material: materials.add(Color::BLACK), diff --git a/src/maze/components.rs b/src/maze/components.rs index badb2b0..fccb97b 100644 --- a/src/maze/components.rs +++ b/src/maze/components.rs @@ -1,18 +1,90 @@ +use crate::floor::components::Floor; + +use super::{errors::MazeConfigError, GlobalMazeConfig}; use bevy::prelude::*; use hexlab::HexMaze; +use hexx::{Hex, HexLayout, HexOrientation}; +use rand::{rngs::StdRng, thread_rng, Rng, SeedableRng}; #[derive(Debug, Reflect, Component)] #[reflect(Component)] -pub(crate) struct Maze(pub(crate) HexMaze); +#[require(MazeConfig, Floor)] +pub struct Maze(pub HexMaze); #[derive(Debug, Reflect, Component)] #[reflect(Component)] -pub(crate) struct Floor(pub(crate) u8); +pub struct Tile; #[derive(Debug, Reflect, Component)] #[reflect(Component)] -pub(crate) struct Tile; +pub struct Wall; -#[derive(Debug, Reflect, Component)] +#[derive(Debug, Reflect, Component, Clone)] #[reflect(Component)] -pub(crate) struct Wall; +pub struct MazeConfig { + pub radius: u32, + pub start_pos: Hex, + pub end_pos: Hex, + pub seed: u64, + pub layout: HexLayout, +} + +impl MazeConfig { + fn new( + radius: u32, + orientation: HexOrientation, + seed: Option, + global_conig: &GlobalMazeConfig, + ) -> Result { + let seed = seed.unwrap_or_else(|| thread_rng().gen()); + let mut rng = StdRng::seed_from_u64(seed); + + let start_pos = generate_pos(radius, &mut rng)?; + let end_pos = generate_pos(radius, &mut rng)?; + + info!("Start pos: (q={}, r={})", start_pos.x, start_pos.y); + info!("End pos: (q={}, r={})", end_pos.x, end_pos.y); + + let layout = HexLayout { + orientation, + hex_size: Vec2::splat(global_conig.hex_size), + ..default() + }; + + Ok(Self { + radius, + start_pos, + end_pos, + seed, + layout, + }) + } + + pub fn new_unchecked( + radius: u32, + orientation: HexOrientation, + seed: Option, + global_conig: &GlobalMazeConfig, + ) -> Self { + Self::new(radius, orientation, seed, global_conig) + .expect("Failed to create MazeConfig with supposedly safe values") + } + + pub fn update(&mut self, global_conig: &GlobalMazeConfig) { + self.layout.hex_size = Vec2::splat(global_conig.hex_size); + } +} + +impl Default for MazeConfig { + fn default() -> Self { + Self::new_unchecked(7, HexOrientation::Flat, None, &GlobalMazeConfig::default()) + } +} + +fn generate_pos(radius: u32, rng: &mut R) -> Result { + let radius = i32::try_from(radius)?; + Ok(Hex::new( + rng.gen_range(-radius..radius), + rng.gen_range(-radius..radius), + )) +} diff --git a/src/maze/errors.rs b/src/maze/errors.rs new file mode 100644 index 0000000..52b78b3 --- /dev/null +++ b/src/maze/errors.rs @@ -0,0 +1,10 @@ +use std::num::TryFromIntError; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum MazeConfigError { + #[error("Failed to convert radius from u32 to i32: {0}")] + RadiusConverions(#[from] TryFromIntError), + #[error("Invalid maze configuration: {0}")] + InvalidConfig(String), +} diff --git a/src/maze/events.rs b/src/maze/events.rs index 2a10115..4f2dcb4 100644 --- a/src/maze/events.rs +++ b/src/maze/events.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; #[derive(Debug, Event)] -pub(crate) struct RecreateMazeEvent { - pub(crate) floor: u8, +pub struct RecreateMazeEvent { + pub floor: u8, } diff --git a/src/maze/mod.rs b/src/maze/mod.rs index db58ab1..dcf6a50 100644 --- a/src/maze/mod.rs +++ b/src/maze/mod.rs @@ -2,14 +2,15 @@ use bevy::{ecs::system::RunSystemOnce, prelude::*}; use events::RecreateMazeEvent; mod assets; pub mod components; +pub mod errors; pub mod events; -mod resources; +pub mod resources; mod systems; -pub use resources::{MazeConfig, MazePluginLoaded}; +pub use resources::{GlobalMazeConfig, MazePluginLoaded}; pub(super) fn plugin(app: &mut App) { - app.init_resource::() + app.init_resource::() .add_event::() .add_plugins(systems::plugin); } diff --git a/src/maze/resources.rs b/src/maze/resources.rs index 0f24456..aa6a31e 100644 --- a/src/maze/resources.rs +++ b/src/maze/resources.rs @@ -1,76 +1,18 @@ use bevy::prelude::*; -use hexx::{Hex, HexLayout, HexOrientation}; -use rand::{rngs::StdRng, thread_rng, Rng, SeedableRng}; -use std::num::TryFromIntError; -use thiserror::Error; #[derive(Debug, Default, Reflect, Resource)] #[reflect(Resource)] pub struct MazePluginLoaded; -#[derive(Debug, Error)] -pub enum MazeConfigError { - #[error("Failed to convert radius from u32 to i32: {0}")] - RadiusConverions(#[from] TryFromIntError), -} - #[derive(Debug, Reflect, Resource)] #[reflect(Resource)] -pub struct MazeConfig { - pub radius: u32, - pub height: f32, +pub struct GlobalMazeConfig { pub hex_size: f32, - pub start_pos: Hex, - pub end_pos: Hex, - pub seed: u64, - pub layout: HexLayout, + pub wall_thickness: f32, + pub height: f32, } -impl MazeConfig { - fn new( - radius: u32, - height: f32, - hex_size: f32, - orientation: HexOrientation, - seed: Option, - ) -> Result { - let seed = seed.unwrap_or_else(|| thread_rng().gen()); - let mut rng = StdRng::seed_from_u64(seed); - - let start_pos = generate_pos(radius, &mut rng)?; - let end_pos = generate_pos(radius, &mut rng)?; - - info!("Start pos: (q={}, r={})", start_pos.x, start_pos.y); - info!("End pos: (q={}, r={})", end_pos.x, end_pos.y); - - let layout = HexLayout { - orientation, - hex_size: Vec2::splat(hex_size), - ..default() - }; - - Ok(Self { - radius, - height, - hex_size, - start_pos, - end_pos, - seed, - layout, - }) - } - - pub fn new_unchecked( - radius: u32, - height: f32, - hex_size: f32, - orientation: HexOrientation, - seed: Option, - ) -> Self { - Self::new(radius, height, hex_size, orientation, seed) - .expect("Failed to create MazeConfig with supposedly safe values") - } - +impl GlobalMazeConfig { pub fn wall_size(&self) -> f32 { self.hex_size / 6. } @@ -78,22 +20,14 @@ impl MazeConfig { pub fn wall_offset(&self) -> f32 { self.hex_size - self.wall_size() } - - pub fn update(&mut self) { - self.layout.hex_size = Vec2::splat(self.hex_size); - } } -impl Default for MazeConfig { +impl Default for GlobalMazeConfig { fn default() -> Self { - Self::new_unchecked(7, 20., 6., HexOrientation::Flat, None) + Self { + hex_size: 6., + wall_thickness: 1., + height: 20., + } } } - -fn generate_pos(radius: u32, rng: &mut R) -> Result { - let radius = i32::try_from(radius)?; - Ok(Hex::new( - rng.gen_range(-radius..radius), - rng.gen_range(-radius..radius), - )) -} diff --git a/src/maze/systems/despawn.rs b/src/maze/systems/despawn.rs index 16385f1..1a725c2 100644 --- a/src/maze/systems/despawn.rs +++ b/src/maze/systems/despawn.rs @@ -1,4 +1,4 @@ -use crate::maze::components::Floor; +use crate::floor::components::Floor; use bevy::prelude::*; pub(crate) fn despawn_floor( diff --git a/src/maze/systems/recreation.rs b/src/maze/systems/recreation.rs index 358e458..f8cb508 100644 --- a/src/maze/systems/recreation.rs +++ b/src/maze/systems/recreation.rs @@ -1,19 +1,29 @@ use bevy::prelude::*; -use crate::maze::{components::Floor, events::RecreateMazeEvent, MazeConfig}; +use crate::{ + floor::components::Floor, + maze::{components::MazeConfig, events::RecreateMazeEvent, GlobalMazeConfig}, +}; use super::{despawn::despawn_floor, spawn::spawn_floor}; pub(crate) fn recreate_maze( mut commands: Commands, mut meshes: ResMut>, - mut materials: ResMut>, - config: Res, query: Query<(Entity, &Floor)>, mut event_reader: EventReader, + mut materials: ResMut>, + global_config: Res, ) { + let maze_config = MazeConfig::default(); for event in event_reader.read() { despawn_floor(&mut commands, &query, event.floor); - spawn_floor(&mut commands, &mut meshes, &mut materials, &config); + spawn_floor( + &mut commands, + &mut meshes, + &mut materials, + &maze_config, + &global_config, + ); } } diff --git a/src/maze/systems/setup.rs b/src/maze/systems/setup.rs index 113cf89..48124a0 100644 --- a/src/maze/systems/setup.rs +++ b/src/maze/systems/setup.rs @@ -1,12 +1,19 @@ use super::spawn::spawn_floor; -use crate::maze::MazeConfig; +use crate::maze::{components::MazeConfig, resources::GlobalMazeConfig}; use bevy::prelude::*; pub(crate) fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, - config: Res, + global_config: Res, ) { - spawn_floor(&mut commands, &mut meshes, &mut materials, &config); + let maze_config = MazeConfig::default(); + spawn_floor( + &mut commands, + &mut meshes, + &mut materials, + &maze_config, + &global_config, + ); } diff --git a/src/maze/systems/spawn.rs b/src/maze/systems/spawn.rs index 8cb229c..1178244 100644 --- a/src/maze/systems/spawn.rs +++ b/src/maze/systems/spawn.rs @@ -1,7 +1,10 @@ -use crate::maze::{ - assets::MazeAssets, - components::{Floor, Maze, Tile, Wall}, - MazeConfig, +use crate::{ + floor::components::Floor, + maze::{ + assets::MazeAssets, + components::{Maze, MazeConfig, Tile, Wall}, + resources::GlobalMazeConfig, + }, }; use bevy::prelude::*; use hexlab::prelude::*; @@ -12,16 +15,17 @@ pub(super) fn spawn_floor( commands: &mut Commands, meshes: &mut ResMut>, materials: &mut ResMut>, - config: &MazeConfig, + maze_config: &MazeConfig, + global_config: &GlobalMazeConfig, ) { let maze = MazeBuilder::new() - .with_radius(config.radius) - .with_seed(config.seed) + .with_radius(maze_config.radius) + .with_seed(maze_config.seed) .with_generator(GeneratorType::RecursiveBacktracking) .build() .expect("Something went wrong while creating maze"); - let assets = MazeAssets::new(meshes, materials, config); + let assets = MazeAssets::new(meshes, materials, global_config); commands .spawn(( Name::new("Floor"), @@ -32,7 +36,7 @@ pub(super) fn spawn_floor( )) .with_children(|parent| { for tile in maze.values() { - spawn_single_hex_tile(parent, &assets, tile, config) + spawn_single_hex_tile(parent, &assets, tile, maze_config, global_config) } }); } @@ -41,10 +45,11 @@ pub(super) fn spawn_single_hex_tile( parent: &mut ChildBuilder, assets: &MazeAssets, tile: &HexTile, - config: &MazeConfig, + maze_config: &MazeConfig, + global_config: &GlobalMazeConfig, ) { - let world_pos = tile.to_vec3(&config.layout); - let rotation = match config.layout.orientation { + let world_pos = tile.to_vec3(&maze_config.layout); + let rotation = match maze_config.layout.orientation { HexOrientation::Pointy => Quat::from_rotation_y(0.0), HexOrientation::Flat => Quat::from_rotation_y(FRAC_PI_6), // 30 degrees rotation }; @@ -57,12 +62,17 @@ pub(super) fn spawn_single_hex_tile( MeshMaterial3d(assets.hex_material.clone()), Transform::from_translation(world_pos).with_rotation(rotation), )) - .with_children(|parent| spawn_walls(parent, assets, config, tile.walls())); + .with_children(|parent| spawn_walls(parent, assets, tile.walls(), global_config)); } -fn spawn_walls(parent: &mut ChildBuilder, assets: &MazeAssets, config: &MazeConfig, walls: &Walls) { +fn spawn_walls( + parent: &mut ChildBuilder, + assets: &MazeAssets, + walls: &Walls, + global_config: &GlobalMazeConfig, +) { let z_rotation = Quat::from_rotation_z(-FRAC_PI_2); - let y_offset = config.height / 2.; + let y_offset = global_config.height / 2.; for i in 0..6 { if !walls.contains(i) { @@ -71,8 +81,8 @@ fn spawn_walls(parent: &mut ChildBuilder, assets: &MazeAssets, config: &MazeConf let wall_angle = -FRAC_PI_3 * i as f32; - let x_offset = config.wall_offset() * f32::cos(wall_angle); - let z_offset = config.wall_offset() * f32::sin(wall_angle); + let x_offset = global_config.wall_offset() * f32::cos(wall_angle); + let z_offset = global_config.wall_offset() * f32::sin(wall_angle); let pos = Vec3::new(x_offset, y_offset, z_offset); let x_rotation = Quat::from_rotation_x(wall_angle + FRAC_PI_2); diff --git a/src/player/systems/input.rs b/src/player/systems/input.rs index 6163700..78d4ed4 100644 --- a/src/player/systems/input.rs +++ b/src/player/systems/input.rs @@ -1,8 +1,6 @@ use crate::{ - maze::{ - components::{Floor, Maze}, - MazeConfig, - }, + floor::components::{CurrentFloor, Floor}, + maze::components::{Maze, MazeConfig}, player::components::{CurrentPosition, MovementTarget, Player}, }; use bevy::prelude::*; @@ -47,10 +45,9 @@ fn create_direction( pub(super) fn player_input( input: Res>, mut player_query: Query<(&mut MovementTarget, &CurrentPosition), With>, - maze_query: Query<(&Maze, &Floor)>, - maze_config: Res, + maze_query: Query<(&Maze, &MazeConfig), With>, ) { - let Ok((maze, _floor)) = maze_query.get_single() else { + let Ok((maze, maze_config)) = maze_query.get_single() else { return; }; diff --git a/src/player/systems/movement.rs b/src/player/systems/movement.rs index 26ec3d2..a27cf02 100644 --- a/src/player/systems/movement.rs +++ b/src/player/systems/movement.rs @@ -1,5 +1,6 @@ use crate::{ - maze::MazeConfig, + floor::components::CurrentFloor, + maze::components::MazeConfig, player::components::{CurrentPosition, MovementSpeed, MovementTarget, Player}, }; use bevy::prelude::*; @@ -16,8 +17,9 @@ pub(super) fn player_movement( ), With, >, - maze_config: Res, + maze_config_query: Query<&MazeConfig, With>, ) { + let maze_config = maze_config_query.single(); for (mut target, speed, mut current_hex, mut transform) in query.iter_mut() { if let Some(target_hex) = target.0 { let current_pos = transform.translation; diff --git a/src/player/systems/respawn.rs b/src/player/systems/respawn.rs index af2446a..da8b264 100644 --- a/src/player/systems/respawn.rs +++ b/src/player/systems/respawn.rs @@ -1,5 +1,6 @@ use crate::{ - maze::MazeConfig, + floor::components::CurrentFloor, + maze::{components::MazeConfig, GlobalMazeConfig}, player::{components::Player, events::RespawnPlayer}, }; use bevy::prelude::*; @@ -8,14 +9,22 @@ use super::{despawn::despawn_players, spawn::spawn_player}; pub(crate) fn respawn_player( mut commands: Commands, + query: Query>, + maze_config_query: Query<&MazeConfig, With>, + mut event_reader: EventReader, mut meshes: ResMut>, mut materials: ResMut>, - config: Res, - query: Query>, - mut event_reader: EventReader, + global_config: Res, ) { + let maze_config = maze_config_query.single(); for _ in event_reader.read() { despawn_players(&mut commands, &query); - spawn_player(&mut commands, &mut meshes, &mut materials, &config); + spawn_player( + &mut commands, + &mut meshes, + &mut materials, + &maze_config, + &global_config, + ); } } diff --git a/src/player/systems/setup.rs b/src/player/systems/setup.rs index 4092d52..85261d2 100644 --- a/src/player/systems/setup.rs +++ b/src/player/systems/setup.rs @@ -1,6 +1,9 @@ use bevy::prelude::*; -use crate::maze::MazeConfig; +use crate::{ + floor::components::CurrentFloor, + maze::{components::MazeConfig, GlobalMazeConfig}, +}; use super::spawn::spawn_player; @@ -8,7 +11,15 @@ pub(crate) fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, - config: Res, + maze_config_query: Query<&MazeConfig, With>, + global_config: Res, ) { - spawn_player(&mut commands, &mut meshes, &mut materials, &config); + let maze_config = maze_config_query.single(); + spawn_player( + &mut commands, + &mut meshes, + &mut materials, + &maze_config, + &global_config, + ); } diff --git a/src/player/systems/spawn.rs b/src/player/systems/spawn.rs index 19a5a85..e28b667 100644 --- a/src/player/systems/spawn.rs +++ b/src/player/systems/spawn.rs @@ -1,5 +1,5 @@ use crate::{ - maze::MazeConfig, + maze::{components::MazeConfig, GlobalMazeConfig}, player::{ assets::{blue_material, generate_pill_mesh}, components::{CurrentPosition, Player}, @@ -11,19 +11,20 @@ pub(super) fn spawn_player( commands: &mut Commands, meshes: &mut ResMut>, materials: &mut ResMut>, - config: &MazeConfig, + maze_config: &MazeConfig, + global_config: &GlobalMazeConfig, ) { - let player_radius = config.hex_size * 0.5; + let player_radius = global_config.hex_size * 0.5; let player_height = player_radius * 3.5; - let y_offset = config.height / 2. + player_height / 1.3; + let y_offset = global_config.height / 2. + player_height / 1.3; - let start_pos = config.layout.hex_to_world_pos(config.start_pos); + let start_pos = maze_config.layout.hex_to_world_pos(maze_config.start_pos); commands.spawn(( Name::new("Player"), Player, - CurrentPosition(config.start_pos), + CurrentPosition(maze_config.start_pos), Mesh3d(meshes.add(generate_pill_mesh(player_radius, player_height / 2.))), MeshMaterial3d(materials.add(blue_material())), Transform::from_xyz(start_pos.x, y_offset, start_pos.y),