diff --git a/Cargo.lock b/Cargo.lock index 3418ad3..354b1a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2112,15 +2112,6 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" -[[package]] -name = "bvh2d" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ee0a309eb56478856a9adc57323d1abc3455be416341e6017f7d9c96ee326b" -dependencies = [ - "glam", -] - [[package]] name = "bytecheck" version = "0.6.12" @@ -3108,16 +3099,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "feeef44e73baff3a26d371801df019877a9866a8c493d315ab00177843314f35" -[[package]] -name = "earcutr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79127ed59a85d7687c409e9978547cffb7dc79675355ed22da6b66fd5f6ead01" -dependencies = [ - "itertools 0.11.0", - "num-traits", -] - [[package]] name = "ecolor" version = "0.30.0" @@ -3420,12 +3401,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "float_next_after" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" - [[package]] name = "fnv" version = "1.0.7" @@ -3671,46 +3646,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "geo" -version = "0.29.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f0e6e028c581e82e6822a68869514e94c25e7f8ea669a2d8595bdf7461ccc5" -dependencies = [ - "earcutr", - "float_next_after", - "geo-types", - "geographiclib-rs", - "i_overlay", - "log", - "num-traits", - "robust", - "rstar", - "spade", -] - -[[package]] -name = "geo-types" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd1157f0f936bf0cd68dec91e8f7c311afe60295574d62b70d4861a1bfdf2d9" -dependencies = [ - "approx", - "num-traits", - "rayon", - "rstar", - "serde", -] - -[[package]] -name = "geographiclib-rs" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e5ed84f8089c70234b0a8e0aedb6dc733671612ddc0d37c6066052f9781960" -dependencies = [ - "libm", -] - [[package]] name = "gethostname" version = "0.4.3" @@ -3800,7 +3735,6 @@ version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" dependencies = [ - "approx", "bytemuck", "rand 0.8.5", "serde", @@ -3955,15 +3889,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -4005,16 +3930,6 @@ dependencies = [ "foldhash", ] -[[package]] -name = "heapless" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" -dependencies = [ - "hash32", - "stable_deref_trait", -] - [[package]] name = "heck" version = "0.5.0" @@ -4278,50 +4193,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "i_float" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775f9961a8d2f879725da8aff789bb20a3ddf297473e0c90af75e69313919490" -dependencies = [ - "serde", -] - -[[package]] -name = "i_key_sort" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347c253b4748a1a28baf94c9ce133b6b166f08573157e05afe718812bc599fcd" - -[[package]] -name = "i_overlay" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01882ce5ed786bf6e8f5167f171a4026cd129ce17d9ff5cbf1e6749b98628ece" -dependencies = [ - "i_float", - "i_key_sort", - "i_shape", - "i_tree", - "rayon", -] - -[[package]] -name = "i_shape" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27dbe9e5238d6b9c694c08415bf00fb370b089949bd818ab01f41f8927b8774c" -dependencies = [ - "i_float", - "serde", -] - -[[package]] -name = "i_tree" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155181bc97d770181cf9477da51218a19ee92a8e5be642e796661aee2b601139" - [[package]] name = "iana-time-zone" version = "0.1.61" @@ -4634,15 +4505,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.12.1" @@ -5003,7 +4865,6 @@ dependencies = [ "thiserror 2.0.11", "trunk", "uuid", - "vleue_navigator", ] [[package]] @@ -6301,22 +6162,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" -[[package]] -name = "polyanya" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d3ef5978f6c2550809ecda6920b6cbac8e11f39ca821362f6c22f29b7aac50" -dependencies = [ - "bvh2d", - "geo", - "glam", - "hashbrown 0.15.2", - "log", - "smallvec", - "spade", - "thiserror 1.0.69", -] - [[package]] name = "portable-atomic" version = "1.10.0" @@ -6981,17 +6826,6 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" -[[package]] -name = "rstar" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421400d13ccfd26dfa5858199c30a5d76f9c54e0dba7575273025b43c5175dbb" -dependencies = [ - "heapless", - "num-traits", - "smallvec", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -8556,17 +8390,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "vleue_navigator" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3594f6304030e531c36a377369d1fe064ebebc89d185bd83a0f27833700b392d" -dependencies = [ - "bevy", - "itertools 0.13.0", - "polyanya", -] - [[package]] name = "vlq" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index deb1729..76c9e5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,6 @@ serde_json = "1.0.138" strum = "0.26.3" thiserror = "2.0.11" uuid = { version = "1.12.1", features = ["js"] } -vleue_navigator = "0.11.1" [target.'cfg(target_arch = "x86_64")'.dependencies] bevy_remote_inspector = "0.1.0" diff --git a/src/actor.rs b/src/actor.rs index 57c28b4..080b2c7 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -97,7 +97,6 @@ use serde::Deserialize; use serde::Serialize; use std::f32::consts::PI; use uuid::Uuid; -use vleue_navigator::prelude::PrimitiveObstacle; use witch::WitchWandSprite; /// アクターの種類を表します @@ -327,8 +326,6 @@ impl Actor { pub fn get_total_scale_factor(&self) -> f32 { let mut scale_factor: f32 = -1.0; - // todo - for wand in self.wands.iter() { for slot in &wand.slots { scale_factor += match slot { @@ -1290,21 +1287,6 @@ pub fn spawn_actor( }, )); - // ナビメッシュの再構築は重いため、本棚のような固定のアクターのみ PrimitiveObstacle を設定します - // アクターが破壊されるとナビメッシュを再計算します - if actor_group == ActorGroup::Entity && props.body_type == BodyType::Fixed { - let scale = 1.0; - builder.insert(match props.collider { - ActorCollider::Ball(radius) => { - (PrimitiveObstacle::Circle(Circle::new(radius * scale)),) - } - ActorCollider::Cuboid(width, height) => (PrimitiveObstacle::Rectangle(Rectangle::new( - width * 2.0 * scale, - height * 2.0 * scale, - )),), - }); - } - builder.with_children(|mut parent| { // 影 if let Some(shadow) = &props.shadow { diff --git a/src/game.rs b/src/game.rs index 806bace..c9bbd94 100644 --- a/src/game.rs +++ b/src/game.rs @@ -118,9 +118,6 @@ use bevy_rapier2d::prelude::*; use bevy_simple_text_input::TextInputPlugin; use bevy_simple_websocket::WebSocketPlugin; use std::num::NonZero; -use vleue_navigator::prelude::NavmeshUpdaterPlugin; -use vleue_navigator::prelude::PrimitiveObstacle; -use vleue_navigator::VleueNavigatorPlugin; pub fn run_game() { let mut app = App::new(); @@ -194,8 +191,6 @@ pub fn run_game() { .add_systems(Startup, setup_rapier_context) .add_plugins(Light2dPlugin) .add_plugins(TextInputPlugin) - .add_plugins(VleueNavigatorPlugin) - .add_plugins(NavmeshUpdaterPlugin::::default()) .add_plugins(EguiPlugin) // // 以下はこのゲーム本体で定義されたプラグイン diff --git a/src/level.rs b/src/level.rs index 0a3e0ac..924992f 100644 --- a/src/level.rs +++ b/src/level.rs @@ -3,7 +3,6 @@ pub mod ceil; pub mod chunk; pub mod collision; pub mod entities; -pub mod navigation; pub mod spawn; pub mod tile; pub mod world; diff --git a/src/level/chunk.rs b/src/level/chunk.rs index 2a6380a..05d4129 100644 --- a/src/level/chunk.rs +++ b/src/level/chunk.rs @@ -44,7 +44,6 @@ pub struct LevelChunk { pub entities: Vec, pub bounds: Bounds, pub dirty_scriptes: Option, - pub dirty_navmesh: bool, } impl LevelChunk { @@ -157,7 +156,6 @@ impl LevelChunk { max_y, }) }, - dirty_navmesh: true, }; } diff --git a/src/level/collision.rs b/src/level/collision.rs index 7055de7..6929bf8 100644 --- a/src/level/collision.rs +++ b/src/level/collision.rs @@ -12,7 +12,6 @@ use bevy_rapier2d::prelude::Collider; use bevy_rapier2d::prelude::Friction; use bevy_rapier2d::prelude::RigidBody; use std::collections::HashMap; -use vleue_navigator::prelude::PrimitiveObstacle; /// 壁タイルから衝突矩形を計算します /// チェストや本棚なども侵入不可能ですが、それらは個別に衝突形状を持つため、ここでは壁のみを扱います @@ -115,7 +114,6 @@ pub fn spawn_wall_collisions(commands: &mut Commands, registry: &Registry, chunk StateScoped(GameState::InGame), Transform::from_translation(Vec3::new(x, y, 0.0)), GlobalTransform::default(), - PrimitiveObstacle::Rectangle(Rectangle::new(w * 2.0, h * 2.0)), Collider::cuboid(w, h), RigidBody::Fixed, Friction { @@ -140,7 +138,6 @@ pub fn spawn_wall_collisions(commands: &mut Commands, registry: &Registry, chunk StateScoped(GameState::InGame), Transform::from_translation(Vec3::new(x, y, 0.0)), GlobalTransform::default(), - PrimitiveObstacle::Rectangle(Rectangle::new(w * 2.0, h * 2.0)), // todo: merge colliders Collider::cuboid(w, h), RigidBody::Fixed, diff --git a/src/level/navigation.rs b/src/level/navigation.rs deleted file mode 100644 index 0a2c62e..0000000 --- a/src/level/navigation.rs +++ /dev/null @@ -1,65 +0,0 @@ -use super::chunk::LevelChunk; -use super::world::GameWorld; -use super::world::LevelScoped; -use crate::level::chunk::index_to_position; -use crate::level::world::GameLevel; -use crate::states::GameState; -use bevy::prelude::*; -use vleue_navigator::prelude::NavMeshSettings; -use vleue_navigator::prelude::NavMeshUpdateMode; -use vleue_navigator::Triangulation; - -#[derive(Component)] -pub struct ChunkNavMesh { - pub level: GameLevel, -} - -// ナビゲーションメッシュを作成します -// ナビメッシュ生成は重いためチャンクごとに生成します -// このため、敵キャラクターがレベル境界を越えて接近することはありません -pub fn spawn_navigation_mesh(commands: &mut Commands, chunk: &LevelChunk) { - commands.spawn(( - StateScoped(GameState::InGame), - LevelScoped(chunk.level.clone()), - ChunkNavMesh { - level: chunk.level.clone(), - }, - NavMeshSettings { - // デスクトップ版では問題ないが、ブラウザ版ではナビメッシュの生成がかなり重い - // 4.0 で少し改善する? - simplify: 4.0, - // Define the outer borders of the navmesh. - fixed: Triangulation::from_outer_edges(&[ - // ここ半タイルぶんズレてる? - index_to_position((chunk.bounds.min_x, chunk.bounds.min_y)), - index_to_position((chunk.bounds.max_x, chunk.bounds.min_y)), - index_to_position((chunk.bounds.max_x, chunk.bounds.max_y)), - index_to_position((chunk.bounds.min_x, chunk.bounds.max_y)), - ]), - - // 小さすぎると、わずかな隙間を通り抜けようとしたり、 - // 曲がり角で壁に近すぎて減速してしまいます - // 大きすぎると、対象が壁際にいるときに移動不可能な目的地になってしまうので、 - // パスが見つけられなくなってしまいます - // Actorのデフォルトが5なので、それに合わせています - agent_radius: 5.0, - ..default() - }, - // todo - // ナビゲーションメッシュ生成は重くDebouncedはWASMで実用的でない - NavMeshUpdateMode::OnDemand(true), - Transform::from_translation(Vec3::ZERO), - )); -} - -pub fn update_dirty_navmesh( - mut world: ResMut, - mut navmesh_query: Query<(&ChunkNavMesh, &mut NavMeshUpdateMode)>, -) { - for (chunk_navmesh, mut update_mode) in navmesh_query.iter_mut() { - if let Some(chunk) = world.get_chunk_mut(&chunk_navmesh.level) { - *update_mode = NavMeshUpdateMode::OnDemand(true); - chunk.dirty_navmesh = false; - } - } -} diff --git a/src/level/world.rs b/src/level/world.rs index 0fa04d5..0c04977 100644 --- a/src/level/world.rs +++ b/src/level/world.rs @@ -59,6 +59,7 @@ impl GameWorld { self.chunks.iter().find(|chunk| chunk.level == *level) } + #[allow(dead_code)] pub fn get_chunk_mut(&mut self, level: &GameLevel) -> Option<&mut LevelChunk> { self.chunks.iter_mut().find(|chunk| chunk.level == *level) } diff --git a/src/page/in_game.rs b/src/page/in_game.rs index 777a6e2..84be9ca 100644 --- a/src/page/in_game.rs +++ b/src/page/in_game.rs @@ -21,8 +21,6 @@ use crate::level::collision::WallCollider; use crate::level::entities::spawn_entity; use crate::level::entities::Spawn; use crate::level::entities::SpawnEvent; -use crate::level::navigation::spawn_navigation_mesh; -use crate::level::navigation::update_dirty_navmesh; use crate::level::spawn::spawn_random_enemies; use crate::level::tile::Tile; use crate::level::world::GameLevel; @@ -97,13 +95,7 @@ pub fn setup_game_world( world.chunks.push(center_chunk.clone()); // 各レベルのエンティティを生成します - spawn_level_entities_and_navmesh( - &mut commands, - ®istry, - &mut spawn, - &mut rng, - ¢er_chunk, - ); + spawn_level_entities_and_navmesh(®istry, &mut spawn, &mut rng, ¢er_chunk); // プレイヤーキャラクターの生成 /////////////////////////////////////////////////////////////////////////////////////////// // エントリーポイントをランダムに選択 @@ -150,7 +142,6 @@ pub fn setup_game_world( } fn spawn_level_entities_and_navmesh( - mut commands: &mut Commands, registry: &Registry, mut spawn: &mut EventWriter, mut rng: &mut StdRng, @@ -160,8 +151,6 @@ fn spawn_level_entities_and_navmesh( let props = registry.get_level(&level); - spawn_navigation_mesh(&mut commands, &chunk); - // エンティティ生成 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 宝箱や灯篭などのエンティティを生成します @@ -224,7 +213,6 @@ fn spawn_level_entities_and_navmesh( } fn spawn_neighbor_chunks( - mut commands: Commands, registry: Registry, mut world: ResMut, mut spawn: EventWriter, @@ -244,13 +232,7 @@ fn spawn_neighbor_chunks( if world.get_chunk(neighbor).is_none() { let chunk = LevelChunk::new(®istry, neighbor, true); world.chunks.push(chunk.clone()); - spawn_level_entities_and_navmesh( - &mut commands, - ®istry, - &mut spawn, - &mut rng, - &chunk, - ); + spawn_level_entities_and_navmesh(®istry, &mut spawn, &mut rng, &chunk); // チャンクの生成は重い処理になるため、1フレームで生成するチャンクは最大ひとつ return; @@ -426,7 +408,6 @@ fn update_lazy_tile_sprites( indiceis_to_spawn.push(chunk.bounds.min_y + chunk.loading_index); - // todo これが重い? clear_tiles_by_bounds( &mut commands, &tiles_query, @@ -518,13 +499,7 @@ impl Plugin for WorldPlugin { FixedUpdate, ( select_bgm, - ( - spawn_neighbor_chunks, - despawn_chunks, - spawn_entity, - update_dirty_navmesh, - ) - .chain(), + (spawn_neighbor_chunks, despawn_chunks, spawn_entity).chain(), ) .in_set(FixedUpdateGameActiveSet), ); diff --git a/src/strategy.rs b/src/strategy.rs index d71976e..bca0404 100644 --- a/src/strategy.rs +++ b/src/strategy.rs @@ -2,7 +2,6 @@ use crate::actor::Actor; use crate::actor::ActorFireState; use crate::actor::ActorGroup; use crate::collision::SENSOR_GROUPS; -use crate::level::navigation::ChunkNavMesh; use crate::level::world::GameWorld; use crate::registry::actor::ActorPropsByType; use crate::registry::Registry; @@ -16,9 +15,6 @@ use bevy_rapier2d::prelude::QueryFilter; use serde::Deserialize; use std::cmp::Ordering; use std::collections::HashMap; -use vleue_navigator::prelude::ManagedNavMesh; -use vleue_navigator::prelude::NavMeshStatus; -use vleue_navigator::NavMesh; const APPROACH_MERGIN: f32 = 8.0; @@ -100,8 +96,6 @@ fn update( registry: Registry, rapier_context: Query<&RapierContext, With>, mut query: Query<(Entity, &mut Actor, &Transform)>, - navmesh: Query<(&ChunkNavMesh, &ManagedNavMesh, Ref)>, - navmeshes: Res>, setup: Res, ) { let context: &RapierContext = rapier_context.single(); @@ -161,8 +155,6 @@ fn update( origin, &props, &mut actor, - &navmesh, - &navmeshes, next_action_index, action, &setup, @@ -196,11 +188,9 @@ fn execute( origin: Vec2, props: &ActorPropsByType, actor: &mut Actor, - navmesh_query: &Query<(&ChunkNavMesh, &ManagedNavMesh, Ref)>, - navmeshes: &Res>, next_action_index: usize, action: &Action, - setup: &Res, + world: &Res, ) { match action { Action::Sleep => { @@ -252,59 +242,9 @@ fn execute( return; } + // TODO // ナビメッシュでルートを検索 - let Some(chunk) = setup.find_chunk_by_position(origin) else { - return; - }; - - let Some((_, navmesh_handle, status)) = navmesh_query - .iter() - .find(|(n, _, _)| n.level == chunk.level) - else { - return; - }; - - let navmesh = navmeshes.get(navmesh_handle); - - let destination = if *status == NavMeshStatus::Built { - if let Some(navmesh) = navmesh { - let from = origin; - let to = nearest.position; - - if let Some(path) = navmesh.path( - // エンティティの位置そのものを使うと、壁際に近づいたときに agent_radius のマージンに埋もれて - // 到達不可能になってしまうので、タイルの中心を使います - from, to, - ) { - actor.navigation_path = path.path.clone(); - - // ナビメッシュで次の目的地を選定 - // APPROACH_MERGIN以下の近すぎるものは避ける - if let Some(first) = path - .path - .iter() - .filter(|p| APPROACH_MERGIN < (origin - **p).length()) - .collect::>() - .first() - { - **first - } else { - // ここに来ることはない? - warn!("first not found"); - actor.commander.destination - } - } else { - // warn!("path not found, from {:?} to {:?}", from, to); - actor.commander.destination - } - } else { - warn!("navmesh not found"); - actor.commander.destination - } - } else { - // warn!("navmesh not built"); - actor.commander.destination - }; + let destination = origin; actor.commander.destination = destination;