From c05d3aa28fbb82221b8f379e3b5bd327080dd815 Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 21 Jul 2025 15:50:26 +0200 Subject: [PATCH] fix: patrol navigation now first targets the closest point on the path --- .../wave_survival/enemies/enemy_wretched.cpp | 4 ++-- modules/wave_survival/patrol_path.cpp | 18 ++++++++++++------ modules/wave_survival/patrol_path.h | 2 +- project/maps/testmap.tscn | 10 +++++----- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/modules/wave_survival/enemies/enemy_wretched.cpp b/modules/wave_survival/enemies/enemy_wretched.cpp index c09f52ff..fe7ff827 100644 --- a/modules/wave_survival/enemies/enemy_wretched.cpp +++ b/modules/wave_survival/enemies/enemy_wretched.cpp @@ -52,8 +52,8 @@ void WretchedPatrolState::enter_state() { float const max_speed{ get_unit()->get_patrol_speed() }; get_target()->set_movement_speed(max_speed); get_nav()->set_max_speed(max_speed); - this->path_point = this->path->get_closest_point(get_target()->get_global_position()); - get_nav()->set_target_position(this->path->point_at(this->path_point)); + Vector3 const nav_target{ this->path->get_closest_point(get_target()->get_global_position(), &this->path_point) }; + get_nav()->set_target_position(nav_target); } void WretchedPatrolState::process(double delta) { diff --git a/modules/wave_survival/patrol_path.cpp b/modules/wave_survival/patrol_path.cpp index eb296e6c..720a4407 100644 --- a/modules/wave_survival/patrol_path.cpp +++ b/modules/wave_survival/patrol_path.cpp @@ -45,20 +45,26 @@ Vector3 PatrolPath::point_at_unchecked(int const index) const { return this->path.get(index)->get_global_position(); } -int PatrolPath::get_closest_point(Vector3 global_position) { +Vector3 PatrolPath::get_closest_point(Vector3 global_position, int *idx) { int best_choice_idx{ -1 }; float best_choice_distance{ Math::INF }; + Vector3 point{ 0, 0, 0 }; for (int i{ 0 }; i < point_count(); ++i) { int const next_idx{ (i + 1) % point_count() }; Vector3 const current{ point_at(i) }; Vector3 const next{ point_at_unchecked(next_idx) }; Vector3 const path_direction{ (next - current).normalized() }; - Vector3 const direction{ (global_position - current).normalized() }; - float const distance{ global_position.distance_squared_to(next) }; - if (path_direction.dot(direction) > 1.0 && distance < best_choice_distance) { - best_choice_idx = next_idx; + Vector3 const difference{ global_position - current }; + Vector3 const closest{ current + path_direction.dot(difference) * path_direction }; + float const distance{ global_position.distance_squared_to(closest) }; + if (distance < best_choice_distance) { + best_choice_idx = i; best_choice_distance = distance; + point = closest; } } - return best_choice_idx; + if (idx) { + *idx = best_choice_idx; + } + return point; } diff --git a/modules/wave_survival/patrol_path.h b/modules/wave_survival/patrol_path.h index 1b4e9096..fdf0aa6b 100644 --- a/modules/wave_survival/patrol_path.h +++ b/modules/wave_survival/patrol_path.h @@ -17,7 +17,7 @@ public: int point_count() const; Vector3 point_at(int &index) const; Vector3 point_at_unchecked(int const index) const; - int get_closest_point(Vector3 global_position); + Vector3 get_closest_point(Vector3 global_position, int *idx); private: Vector path{}; diff --git a/project/maps/testmap.tscn b/project/maps/testmap.tscn index 6ceac7fc..179bf228 100644 --- a/project/maps/testmap.tscn +++ b/project/maps/testmap.tscn @@ -394,23 +394,23 @@ transform = Transform3D(-0.866023, -0.433016, 0.250001, 0, 0.499998, 0.866027, - shadow_enabled = true [node name="PlayerBody" parent="." instance=ExtResource("1_6t4yh")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0500376, 2.38419e-07, -0.0317376) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.039836764, -0.0014820099, 0.5135803) slide_on_ceiling = false [node name="NpcUnit" type="NpcUnit" parent="." node_paths=PackedStringArray("patrol_path")] patrol_path = NodePath("../PatrolPath") [node name="EnemyWretched" parent="NpcUnit" instance=ExtResource("3_7ng1a")] -transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 0.017590523, 0.023196908, 3.073964) +transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, -0.68063784, 0.023195954, 3.1014705) [node name="EnemyWretched2" parent="NpcUnit" instance=ExtResource("3_7ng1a")] -transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, -1.0904664, 0.023196908, 1.6584808) +transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 1.2873832, 0.023196908, 3.055359) [node name="EnemyWretched3" parent="NpcUnit" instance=ExtResource("3_7ng1a")] -transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 1.1613213, 0.023196908, 1.513694) +transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, -0.2727146, 0.023196908, 4.665185) [node name="EnemyWretched4" parent="NpcUnit" instance=ExtResource("3_7ng1a")] -transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, -0.977286, 0.023196908, 4.202239) +transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, 1.5723263, 0.023197861, 4.477292) [node name="PatrolPath" type="PatrolPath" parent="."]