diff --git a/doc/classes/NavigationAgent.xml b/doc/classes/NavigationAgent.xml
index 7cc4dbdd1..1da8777dc 100644
--- a/doc/classes/NavigationAgent.xml
+++ b/doc/classes/NavigationAgent.xml
@@ -48,7 +48,7 @@
- Returns the object's [RID].
+ Returns the [RID] of this agent on the [NavigationServer].
@@ -101,6 +101,9 @@
The agent height offset to match the navigation mesh height.
+
+ If [code]true[/code] the agent is registered for an RVO avoidance callback on the [NavigationServer]. When [method set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector3 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it.
+
Ignores collisions on the Y axis. Must be [code]true[/code] to move on a horizontal plane.
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 4433ba0e9..e5e981d91 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -48,7 +48,7 @@
- Returns the object's [RID].
+ Returns the [RID] of this agent on the [Navigation2DServer].
@@ -98,6 +98,9 @@
+
+ If [code]true[/code] the agent is registered for an RVO avoidance callback on the [Navigation2DServer]. When [method set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector2 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it.
+
The maximum number of neighbors for the agent to consider.
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 835aa662f..b4ab794f4 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -38,6 +38,9 @@
void NavigationAgent2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent2D::get_rid);
+ ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent2D::set_avoidance_enabled);
+ ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent2D::get_avoidance_enabled);
+
ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance);
ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance);
@@ -83,6 +86,7 @@ void NavigationAgent2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_time_horizon", "get_time_horizon");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01"), "set_max_speed", "get_max_speed");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1"), "set_path_max_distance", "get_path_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached"));
@@ -95,7 +99,7 @@ void NavigationAgent2D::_notification(int p_what) {
case NOTIFICATION_READY: {
agent_parent = Object::cast_to(get_parent());
- Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+ set_avoidance_enabled(avoidance_enabled);
// Search the navigation node and set it
{
@@ -154,6 +158,7 @@ NavigationAgent2D::NavigationAgent2D() :
agent_parent(nullptr),
navigation(nullptr),
agent(RID()),
+ avoidance_enabled(false),
target_desired_distance(1.0),
path_max_distance(3.0),
velocity_submitted(false),
@@ -172,6 +177,19 @@ NavigationAgent2D::~NavigationAgent2D() {
agent = RID(); // Pointless
}
+void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) {
+ avoidance_enabled = p_enabled;
+ if (avoidance_enabled) {
+ Navigation2DServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+ } else {
+ Navigation2DServer::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+ }
+}
+
+bool NavigationAgent2D::get_avoidance_enabled() const {
+ return avoidance_enabled;
+}
+
void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
if (navigation == p_nav) {
return; // Pointless
@@ -298,7 +316,7 @@ void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) {
String NavigationAgent2D::get_configuration_warning() const {
if (!Object::cast_to(get_parent())) {
- return TTR("The NavigationAgent2D can be used only under a Node2D node.");
+ return TTR("The NavigationAgent2D can be used only under a Node2D inheriting parent node.");
}
return String();
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 8ee2c3c53..ee011c9a4 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -44,6 +44,8 @@ class NavigationAgent2D : public Node {
RID agent;
RID map_before_pause;
+ bool avoidance_enabled;
+
real_t target_desired_distance;
real_t radius;
real_t neighbor_dist;
@@ -85,6 +87,9 @@ public:
return agent;
}
+ void set_avoidance_enabled(bool p_enabled);
+ bool get_avoidance_enabled() 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.cpp b/scene/3d/navigation_agent.cpp
index b620f1bd8..a3fe6b97f 100644
--- a/scene/3d/navigation_agent.cpp
+++ b/scene/3d/navigation_agent.cpp
@@ -38,6 +38,9 @@
void NavigationAgent::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationAgent::get_rid);
+ ClassDB::bind_method(D_METHOD("set_avoidance_enabled", "enabled"), &NavigationAgent::set_avoidance_enabled);
+ ClassDB::bind_method(D_METHOD("get_avoidance_enabled"), &NavigationAgent::get_avoidance_enabled);
+
ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent::set_target_desired_distance);
ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent::get_target_desired_distance);
@@ -91,6 +94,7 @@ void NavigationAgent::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_max_speed", "get_max_speed");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", "get_avoidance_enabled");
ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached"));
@@ -103,7 +107,7 @@ void NavigationAgent::_notification(int p_what) {
case NOTIFICATION_READY: {
agent_parent = Object::cast_to(get_parent());
- NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+ set_avoidance_enabled(avoidance_enabled);
// Search the navigation node and set it
{
@@ -162,6 +166,7 @@ NavigationAgent::NavigationAgent() :
agent_parent(nullptr),
navigation(nullptr),
agent(RID()),
+ avoidance_enabled(false),
target_desired_distance(1.0),
navigation_height_offset(0.0),
path_max_distance(3.0),
@@ -182,6 +187,19 @@ NavigationAgent::~NavigationAgent() {
agent = RID(); // Pointless
}
+void NavigationAgent::set_avoidance_enabled(bool p_enabled) {
+ avoidance_enabled = p_enabled;
+ if (avoidance_enabled) {
+ NavigationServer::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+ } else {
+ NavigationServer::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+ }
+}
+
+bool NavigationAgent::get_avoidance_enabled() const {
+ return avoidance_enabled;
+}
+
void NavigationAgent::set_navigation(Navigation *p_nav) {
if (navigation == p_nav) {
return; // Pointless
@@ -316,7 +334,7 @@ void NavigationAgent::_avoidance_done(Vector3 p_new_velocity) {
String NavigationAgent::get_configuration_warning() const {
if (!Object::cast_to(get_parent())) {
- return TTR("The NavigationAgent can be used only under a spatial node.");
+ return TTR("The NavigationAgent can be used only under a Spatial inheriting parent node.");
}
return String();
diff --git a/scene/3d/navigation_agent.h b/scene/3d/navigation_agent.h
index ab7e5f0bc..c6b74badb 100644
--- a/scene/3d/navigation_agent.h
+++ b/scene/3d/navigation_agent.h
@@ -45,6 +45,8 @@ class NavigationAgent : public Node {
RID agent;
RID map_before_pause;
+ bool avoidance_enabled;
+
real_t target_desired_distance;
real_t radius;
real_t navigation_height_offset;
@@ -88,6 +90,9 @@ public:
return agent;
}
+ void set_avoidance_enabled(bool p_enabled);
+ bool get_avoidance_enabled() const;
+
void set_target_desired_distance(real_t p_dd);
real_t get_target_desired_distance() const {
return target_desired_distance;