summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2022-06-14 22:54:13 +0200
committerGitHub <noreply@github.com>2022-06-14 22:54:13 +0200
commitd2a90d62fda657d44478b3e52f24bbed6426cd70 (patch)
treebf353194cb2016e4f38d75427c34735e56f48b97
parent5a76d7128a38e5e46c373a83e396b755d4971da8 (diff)
parentf10ff0efda43d4856ddea5a778e39c114fe6ce80 (diff)
Merge pull request #62044 from smix8/navigation_navagent_map_change_4.x
Add NavigationAgent2D/3D set_navigation_map() function
-rw-r--r--doc/classes/NavigationAgent2D.xml13
-rw-r--r--doc/classes/NavigationAgent3D.xml13
-rw-r--r--scene/2d/navigation_agent_2d.cpp30
-rw-r--r--scene/2d/navigation_agent_2d.h4
-rw-r--r--scene/3d/navigation_agent_3d.cpp30
-rw-r--r--scene/3d/navigation_agent_3d.h4
6 files changed, 90 insertions, 4 deletions
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 945947ad9f..c04e7bf1f7 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].
</description>
</method>
+ <method name="get_navigation_map" qualifiers="const">
+ <return type="RID" />
+ <description>
+ 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.
+ </description>
+ </method>
<method name="get_next_location">
<return type="Vector2" />
<description>
@@ -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].
</description>
</method>
+ <method name="set_navigation_map">
+ <return type="void" />
+ <argument index="0" name="navigation_map" type="RID" />
+ <description>
+ Sets the [RID] of the navigation map this NavigationAgent node should use and also updates the [code]agent[/code] on the NavigationServer.
+ </description>
+ </method>
<method name="set_target_location">
<return type="void" />
<argument index="0" name="location" type="Vector2" />
diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml
index 7f7e058742..91d7aabc34 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].
</description>
</method>
+ <method name="get_navigation_map" qualifiers="const">
+ <return type="RID" />
+ <description>
+ 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.
+ </description>
+ </method>
<method name="get_next_location">
<return type="Vector3" />
<description>
@@ -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].
</description>
</method>
+ <method name="set_navigation_map">
+ <return type="void" />
+ <argument index="0" name="navigation_map" type="RID" />
+ <description>
+ Sets the [RID] of the navigation map this NavigationAgent node should use and also updates the [code]agent[/code] on the NavigationServer.
+ </description>
+ </method>
<method name="set_target_location">
<return type="void" />
<argument index="0" name="location" type="Vector3" />
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 80d60dca17..7186a63452 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<Node2D>(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<Node2D>(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 c9983119d0..4c4880f77e 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 947d6012d5..425c5df126 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<Node3D>(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<Node3D>(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 633bf091d1..8e5cb83f6e 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;