From f10ff0efda43d4856ddea5a778e39c114fe6ce80 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Tue, 14 Jun 2022 20:39:15 +0200 Subject: [PATCH] Add NavigationAgent set_navigation_map() function Add NavigationAgent set_navigation_map() and get_navigation_map() function. --- doc/classes/NavigationAgent2D.xml | 13 +++++++++++++ doc/classes/NavigationAgent3D.xml | 13 +++++++++++++ scene/2d/navigation_agent_2d.cpp | 30 ++++++++++++++++++++++++++++-- scene/2d/navigation_agent_2d.h | 4 ++++ scene/3d/navigation_agent_3d.cpp | 30 ++++++++++++++++++++++++++++-- scene/3d/navigation_agent_3d.h | 4 ++++ 6 files changed, 90 insertions(+), 4 deletions(-) diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml index 945947ad9fd..c04e7bf1f73 100644 --- a/doc/classes/NavigationAgent2D.xml +++ b/doc/classes/NavigationAgent2D.xml @@ -34,6 +34,12 @@ Returns which index the agent is currently on in the navigation path's [PackedVector2Array]. + + + + Returns the [RID] of the navigation map for this NavigationAgent node. This function returns always the map set on the NavigationAgent node and not the map of the abstract agent on the NavigationServer. If the agent map is changed directly with the NavigationServer API the NavigationAgent node will not be aware of the map change. Use [method set_navigation_map] to change the navigation map for the NavigationAgent and also update the agent on the NavigationServer. + + @@ -70,6 +76,13 @@ Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location]. + + + + + Sets the [RID] of the navigation map this NavigationAgent node should use and also updates the [code]agent[/code] on the NavigationServer. + + diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml index 7f7e058742c..91d7aabc345 100644 --- a/doc/classes/NavigationAgent3D.xml +++ b/doc/classes/NavigationAgent3D.xml @@ -34,6 +34,12 @@ Returns which index the agent is currently on in the navigation path's [PackedVector3Array]. + + + + Returns the [RID] of the navigation map for this NavigationAgent node. This function returns always the map set on the NavigationAgent node and not the map of the abstract agent on the NavigationServer. If the agent map is changed directly with the NavigationServer API the NavigationAgent node will not be aware of the map change. Use [method set_navigation_map] to change the navigation map for the NavigationAgent and also update the agent on the NavigationServer. + + @@ -70,6 +76,13 @@ Returns true if the target location is reached. The target location is set using [method set_target_location]. It may not always be possible to reach the target location. It should always be possible to reach the final location though. See [method get_final_location]. + + + + + Sets the [RID] of the navigation map this NavigationAgent node should use and also updates the [code]agent[/code] on the NavigationServer. + + diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index 80d60dca171..7186a634522 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -64,6 +64,9 @@ void NavigationAgent2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_navigable_layers", "navigable_layers"), &NavigationAgent2D::set_navigable_layers); ClassDB::bind_method(D_METHOD("get_navigable_layers"), &NavigationAgent2D::get_navigable_layers); + ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent2D::set_navigation_map); + ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent2D::get_navigation_map); + ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent2D::set_target_location); ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent2D::get_target_location); ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent2D::get_next_location); @@ -191,7 +194,11 @@ void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) { if (Object::cast_to(p_agent_parent) != nullptr) { // place agent on navigation map first or else the RVO agent callback creation fails silently later agent_parent = Object::cast_to(p_agent_parent); - NavigationServer2D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_2d()->get_navigation_map()); + if (map_override.is_valid()) { + NavigationServer2D::get_singleton()->agent_set_map(get_rid(), map_override); + } else { + NavigationServer2D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_2d()->get_navigation_map()); + } // create new avoidance callback if enabled set_avoidance_enabled(avoidance_enabled); } else { @@ -212,6 +219,21 @@ uint32_t NavigationAgent2D::get_navigable_layers() const { return navigable_layers; } +void NavigationAgent2D::set_navigation_map(RID p_navigation_map) { + map_override = p_navigation_map; + NavigationServer2D::get_singleton()->agent_set_map(agent, map_override); + _request_repath(); +} + +RID NavigationAgent2D::get_navigation_map() const { + if (map_override.is_valid()) { + return map_override; + } else if (agent_parent != nullptr) { + return agent_parent->get_world_2d()->get_navigation_map(); + } + return RID(); +} + void NavigationAgent2D::set_target_desired_distance(real_t p_dd) { target_desired_distance = p_dd; } @@ -360,7 +382,11 @@ void NavigationAgent2D::update_navigation() { } if (reload_path) { - navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true, navigable_layers); + if (map_override.is_valid()) { + navigation_path = NavigationServer2D::get_singleton()->map_get_path(map_override, o, target_location, true, navigable_layers); + } else { + navigation_path = NavigationServer2D::get_singleton()->map_get_path(agent_parent->get_world_2d()->get_navigation_map(), o, target_location, true, navigable_layers); + } navigation_finished = false; nav_path_index = 0; emit_signal(SNAME("path_changed")); diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index c9983119d07..4c4880f77e5 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -42,6 +42,7 @@ class NavigationAgent2D : public Node { RID agent; RID map_before_pause; + RID map_override; bool avoidance_enabled = false; uint32_t navigable_layers = 1; @@ -87,6 +88,9 @@ public: void set_navigable_layers(uint32_t p_layers); uint32_t get_navigable_layers() const; + void set_navigation_map(RID p_navigation_map); + RID get_navigation_map() const; + void set_target_desired_distance(real_t p_dd); real_t get_target_desired_distance() const { return target_desired_distance; diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 947d6012d5f..425c5df126f 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -68,6 +68,9 @@ void NavigationAgent3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_navigable_layers", "navigable_layers"), &NavigationAgent3D::set_navigable_layers); ClassDB::bind_method(D_METHOD("get_navigable_layers"), &NavigationAgent3D::get_navigable_layers); + ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationAgent3D::set_navigation_map); + ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationAgent3D::get_navigation_map); + ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent3D::set_target_location); ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent3D::get_target_location); ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent3D::get_next_location); @@ -198,7 +201,11 @@ void NavigationAgent3D::set_agent_parent(Node *p_agent_parent) { if (Object::cast_to(p_agent_parent) != nullptr) { // place agent on navigation map first or else the RVO agent callback creation fails silently later agent_parent = Object::cast_to(p_agent_parent); - NavigationServer3D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_3d()->get_navigation_map()); + if (map_override.is_valid()) { + NavigationServer3D::get_singleton()->agent_set_map(get_rid(), map_override); + } else { + NavigationServer3D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_3d()->get_navigation_map()); + } // create new avoidance callback if enabled set_avoidance_enabled(avoidance_enabled); } else { @@ -219,6 +226,21 @@ uint32_t NavigationAgent3D::get_navigable_layers() const { return navigable_layers; } +void NavigationAgent3D::set_navigation_map(RID p_navigation_map) { + map_override = p_navigation_map; + NavigationServer3D::get_singleton()->agent_set_map(agent, map_override); + _request_repath(); +} + +RID NavigationAgent3D::get_navigation_map() const { + if (map_override.is_valid()) { + return map_override; + } else if (agent_parent != nullptr) { + return agent_parent->get_world_3d()->get_navigation_map(); + } + return RID(); +} + void NavigationAgent3D::set_target_desired_distance(real_t p_dd) { target_desired_distance = p_dd; } @@ -377,7 +399,11 @@ void NavigationAgent3D::update_navigation() { } if (reload_path) { - navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true, navigable_layers); + if (map_override.is_valid()) { + navigation_path = NavigationServer3D::get_singleton()->map_get_path(map_override, o, target_location, true, navigable_layers); + } else { + navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true, navigable_layers); + } navigation_finished = false; nav_path_index = 0; emit_signal(SNAME("path_changed")); diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index 633bf091d14..8e5cb83f6e4 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -42,6 +42,7 @@ class NavigationAgent3D : public Node { RID agent; RID map_before_pause; + RID map_override; bool avoidance_enabled = false; uint32_t navigable_layers = 1; @@ -89,6 +90,9 @@ public: void set_navigable_layers(uint32_t p_layers); uint32_t get_navigable_layers() const; + void set_navigation_map(RID p_navigation_map); + RID get_navigation_map() const; + void set_target_desired_distance(real_t p_dd); real_t get_target_desired_distance() const { return target_desired_distance;