Backported from godot4: Add agent pause mode to NavigationServer

Adds agent pause mode to NavigationServer.
- smix8
https://github.com/godotengine/godot/commit/ae9dd47d0c1c237d0733439862aa5ff651dcac2
This commit is contained in:
Relintai 2023-09-04 19:04:29 +02:00
parent 2f036edcc5
commit aeb4d3fbe2
23 changed files with 211 additions and 29 deletions

View File

@ -37,6 +37,13 @@
Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to. Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to.
</description> </description>
</method> </method>
<method name="agent_get_paused" qualifiers="const">
<return type="bool" />
<param index="0" name="agent" type="RID" />
<description>
Returns [code]true[/code] if the specified [param agent] is paused.
</description>
</method>
<method name="agent_is_map_changed" qualifiers="const"> <method name="agent_is_map_changed" qualifiers="const">
<return type="bool" /> <return type="bool" />
<argument index="0" name="agent" type="RID" /> <argument index="0" name="agent" type="RID" />
@ -120,6 +127,14 @@
Sets the maximum distance to other agents this agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe. Sets the maximum distance to other agents this agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe.
</description> </description>
</method> </method>
<method name="agent_set_paused">
<return type="void" />
<param index="0" name="agent" type="RID" />
<param index="1" name="paused" type="bool" />
<description>
If [param paused] is true the specified [param agent] will not be processed, e.g. calculate avoidance velocities or receive avoidance callbacks.
</description>
</method>
<method name="agent_set_position"> <method name="agent_set_position">
<return type="void" /> <return type="void" />
<argument index="0" name="agent" type="RID" /> <argument index="0" name="agent" type="RID" />
@ -487,6 +502,13 @@
Returns the navigation map [RID] the requested [param obstacle] is currently assigned to. Returns the navigation map [RID] the requested [param obstacle] is currently assigned to.
</description> </description>
</method> </method>
<method name="obstacle_get_paused" qualifiers="const">
<return type="bool" />
<param index="0" name="obstacle" type="RID" />
<description>
Returns [code]true[/code] if the specified [param obstacle] is paused.
</description>
</method>
<method name="obstacle_set_avoidance_layers"> <method name="obstacle_set_avoidance_layers">
<return type="void" /> <return type="void" />
<argument index="0" name="obstacle" type="RID" /> <argument index="0" name="obstacle" type="RID" />
@ -502,6 +524,14 @@
Sets the navigation map [RID] for the obstacle. Sets the navigation map [RID] for the obstacle.
</description> </description>
</method> </method>
<method name="obstacle_set_paused">
<return type="void" />
<param index="0" name="obstacle" type="RID" />
<param index="1" name="paused" type="bool" />
<description>
If [param paused] is true the specified [param obstacle] will not be processed, e.g. affect avoidance velocities.
</description>
</method>
<method name="obstacle_set_position"> <method name="obstacle_set_position">
<return type="void" /> <return type="void" />
<argument index="0" name="obstacle" type="RID" /> <argument index="0" name="obstacle" type="RID" />

View File

@ -37,6 +37,13 @@
Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to. Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to.
</description> </description>
</method> </method>
<method name="agent_get_paused" qualifiers="const">
<return type="bool" />
<param index="0" name="agent" type="RID" />
<description>
Returns [code]true[/code] if the specified [param agent] is paused.
</description>
</method>
<method name="agent_get_use_3d_avoidance" qualifiers="const"> <method name="agent_get_use_3d_avoidance" qualifiers="const">
<return type="bool" /> <return type="bool" />
<argument index="0" name="agent" type="RID" /> <argument index="0" name="agent" type="RID" />
@ -135,6 +142,14 @@
Sets the maximum distance to other agents this agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe. Sets the maximum distance to other agents this agent takes into account in the navigation. The larger this number, the longer the running time of the simulation. If the number is too low, the simulation will not be safe.
</description> </description>
</method> </method>
<method name="agent_set_paused">
<return type="void" />
<param index="0" name="agent" type="RID" />
<param index="1" name="paused" type="bool" />
<description>
If [param paused] is true the specified [param agent] will not be processed, e.g. calculate avoidance velocities or receive avoidance callbacks.
</description>
</method>
<method name="agent_set_position"> <method name="agent_set_position">
<return type="void" /> <return type="void" />
<argument index="0" name="agent" type="RID" /> <argument index="0" name="agent" type="RID" />
@ -551,6 +566,13 @@
Returns the navigation map [RID] the requested [param obstacle] is currently assigned to. Returns the navigation map [RID] the requested [param obstacle] is currently assigned to.
</description> </description>
</method> </method>
<method name="obstacle_get_paused" qualifiers="const">
<return type="bool" />
<param index="0" name="obstacle" type="RID" />
<description>
Returns [code]true[/code] if the specified [param obstacle] is paused.
</description>
</method>
<method name="obstacle_set_avoidance_layers"> <method name="obstacle_set_avoidance_layers">
<return type="void" /> <return type="void" />
<argument index="0" name="obstacle" type="RID" /> <argument index="0" name="obstacle" type="RID" />
@ -575,6 +597,14 @@
Assigns the [param obstacle] to a navigation map. Assigns the [param obstacle] to a navigation map.
</description> </description>
</method> </method>
<method name="obstacle_set_paused">
<return type="void" />
<param index="0" name="obstacle" type="RID" />
<param index="1" name="paused" type="bool" />
<description>
If [param paused] is true the specified [param obstacle] will not be processed, e.g. affect avoidance velocities.
</description>
</method>
<method name="obstacle_set_position"> <method name="obstacle_set_position">
<return type="void" /> <return type="void" />
<argument index="0" name="obstacle" type="RID" /> <argument index="0" name="obstacle" type="RID" />

View File

@ -55,6 +55,7 @@ NavAgent::NavAgent() {
agent_dirty = true; agent_dirty = true;
map_update_id = 0; map_update_id = 0;
paused = false;
} }
void NavAgent::set_avoidance_enabled(bool p_enabled) { void NavAgent::set_avoidance_enabled(bool p_enabled) {
@ -331,6 +332,26 @@ const Dictionary NavAgent::get_avoidance_data() const {
return _avoidance_data; return _avoidance_data;
} }
void NavAgent::set_paused(bool p_paused) {
if (paused == p_paused) {
return;
}
paused = p_paused;
if (map) {
if (paused) {
map->remove_agent_as_controlled(this);
} else {
map->set_agent_as_controlled(this);
}
}
}
bool NavAgent::get_paused() const {
return paused;
}
void NavAgent::set_avoidance_callback(ObjectID p_id, const StringName p_method, const Variant p_udata) { void NavAgent::set_avoidance_callback(ObjectID p_id, const StringName p_method, const Variant p_udata) {
avoidance_callback.id = p_id; avoidance_callback.id = p_id;
avoidance_callback.method = p_method; avoidance_callback.method = p_method;

View File

@ -80,6 +80,7 @@ class NavAgent : public NavRid {
bool agent_dirty; bool agent_dirty;
uint32_t map_update_id; uint32_t map_update_id;
bool paused;
public: public:
NavAgent(); NavAgent();
@ -140,6 +141,9 @@ public:
void set_avoidance_priority(real_t p_priority); void set_avoidance_priority(real_t p_priority);
real_t get_avoidance_priority() const { return avoidance_priority; }; real_t get_avoidance_priority() const { return avoidance_priority; };
void set_paused(bool p_paused);
bool get_paused() const;
bool check_dirty(); bool check_dirty();
// Updates this agent with rvo data after the rvo simulation avoidance step. // Updates this agent with rvo data after the rvo simulation avoidance step.

View File

@ -738,6 +738,11 @@ bool NavMap::has_obstacle(NavObstacle *obstacle) const {
} }
void NavMap::add_obstacle(NavObstacle *obstacle) { void NavMap::add_obstacle(NavObstacle *obstacle) {
if (obstacle->get_paused()) {
// No point in adding a paused obstacle, it will add itself when unpaused again.
return;
}
if (!has_obstacle(obstacle)) { if (!has_obstacle(obstacle)) {
obstacles.push_back(obstacle); obstacles.push_back(obstacle);
obstacles_dirty = true; obstacles_dirty = true;
@ -754,6 +759,12 @@ void NavMap::remove_obstacle(NavObstacle *obstacle) {
void NavMap::set_agent_as_controlled(NavAgent *agent) { void NavMap::set_agent_as_controlled(NavAgent *agent) {
remove_agent_as_controlled(agent); remove_agent_as_controlled(agent);
if (agent->get_paused()) {
// No point in adding a paused agent, it will add itself when unpaused again.
return;
}
if (agent->get_use_3d_avoidance()) { if (agent->get_use_3d_avoidance()) {
int64_t agent_3d_index = active_3d_avoidance_agents.find(agent); int64_t agent_3d_index = active_3d_avoidance_agents.find(agent);
if (agent_3d_index < 0) { if (agent_3d_index < 0) {

View File

@ -38,6 +38,7 @@ NavObstacle::NavObstacle() {
avoidance_layers = 1; avoidance_layers = 1;
obstacle_dirty = true; obstacle_dirty = true;
map_update_id = 0; map_update_id = 0;
paused = false;
} }
NavObstacle::~NavObstacle() {} NavObstacle::~NavObstacle() {}
@ -88,3 +89,24 @@ bool NavObstacle::check_dirty() {
obstacle_dirty = false; obstacle_dirty = false;
return was_dirty; return was_dirty;
} }
void NavObstacle::set_paused(bool p_paused) {
if (paused == p_paused) {
return;
}
paused = p_paused;
if (map) {
if (paused) {
map->remove_obstacle(this);
} else {
map->add_obstacle(this);
}
}
//internal_update_agent();
}
bool NavObstacle::get_paused() const {
return paused;
}

View File

@ -32,8 +32,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/ /**************************************************************************/
#include "core/object/class_db.h"
#include "core/containers/local_vector.h" #include "core/containers/local_vector.h"
#include "core/object/class_db.h"
#include "nav_agent.h" #include "nav_agent.h"
#include "nav_rid.h" #include "nav_rid.h"
@ -51,6 +51,7 @@ class NavObstacle : public NavRid {
bool obstacle_dirty; bool obstacle_dirty;
uint32_t map_update_id; uint32_t map_update_id;
bool paused;
public: public:
NavObstacle(); NavObstacle();
@ -73,6 +74,9 @@ public:
void set_avoidance_layers(uint32_t p_layers); void set_avoidance_layers(uint32_t p_layers);
uint32_t get_avoidance_layers() const { return avoidance_layers; }; uint32_t get_avoidance_layers() const { return avoidance_layers; };
void set_paused(bool p_paused);
bool get_paused() const;
bool check_dirty(); bool check_dirty();
}; };

View File

@ -342,6 +342,9 @@ void FORWARD_2(agent_set_position, RID, p_agent, Vector2, p_position, rid_to_rid
bool FORWARD_1_C(agent_is_map_changed, RID, p_agent, rid_to_rid); bool FORWARD_1_C(agent_is_map_changed, RID, p_agent, rid_to_rid);
void FORWARD_2(agent_set_paused, RID, p_agent, bool, p_paused, rid_to_rid, bool_to_bool);
bool FORWARD_1_C(agent_get_paused, RID, p_agent, rid_to_rid);
void FORWARD_1(free, RID, p_object, rid_to_rid); void FORWARD_1(free, RID, p_object, rid_to_rid);
void FORWARD_4(agent_set_avoidance_callback, RID, p_agent, ObjectID, p_object_id, StringName, p_method, Variant, p_udata, rid_to_rid, id_to_id, sn_to_sn, var_to_var); void FORWARD_4(agent_set_avoidance_callback, RID, p_agent, ObjectID, p_object_id, StringName, p_method, Variant, p_udata, rid_to_rid, id_to_id, sn_to_sn, var_to_var);
@ -356,6 +359,8 @@ RID PandemoniumNavigation2DServer::obstacle_create() {
} }
void FORWARD_2(obstacle_set_map, RID, p_obstacle, RID, p_map, rid_to_rid, rid_to_rid); void FORWARD_2(obstacle_set_map, RID, p_obstacle, RID, p_map, rid_to_rid, rid_to_rid);
RID FORWARD_1_C(obstacle_get_map, RID, p_obstacle, rid_to_rid); RID FORWARD_1_C(obstacle_get_map, RID, p_obstacle, rid_to_rid);
void FORWARD_2(obstacle_set_paused, RID, p_obstacle, bool, p_paused, rid_to_rid, bool_to_bool);
bool FORWARD_1_C(obstacle_get_paused, RID, p_obstacle, rid_to_rid);
void FORWARD_2(obstacle_set_position, RID, p_obstacle, Vector2, p_position, rid_to_rid, v2_to_v3); void FORWARD_2(obstacle_set_position, RID, p_obstacle, Vector2, p_position, rid_to_rid, v2_to_v3);
void FORWARD_2(obstacle_set_avoidance_layers, RID, p_obstacle, uint32_t, p_layers, rid_to_rid, uint32_to_uint32); void FORWARD_2(obstacle_set_avoidance_layers, RID, p_obstacle, uint32_t, p_layers, rid_to_rid, uint32_to_uint32);

View File

@ -176,6 +176,9 @@ public:
virtual void agent_set_map(RID p_agent, RID p_map); virtual void agent_set_map(RID p_agent, RID p_map);
virtual RID agent_get_map(RID p_agent) const; virtual RID agent_get_map(RID p_agent) const;
virtual void agent_set_paused(RID p_agent, bool p_paused);
virtual bool agent_get_paused(RID p_agent) const;
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled); virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled);
virtual bool agent_get_avoidance_enabled(RID p_agent) const; virtual bool agent_get_avoidance_enabled(RID p_agent) const;
@ -239,6 +242,10 @@ public:
virtual RID obstacle_create(); virtual RID obstacle_create();
virtual void obstacle_set_map(RID p_obstacle, RID p_map); virtual void obstacle_set_map(RID p_obstacle, RID p_map);
virtual RID obstacle_get_map(RID p_obstacle) const; virtual RID obstacle_get_map(RID p_obstacle) const;
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused);
virtual bool obstacle_get_paused(RID p_obstacle) const;
virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position); virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position);
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices); virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices);
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers); virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers);

View File

@ -730,6 +730,20 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
} }
} }
COMMAND_2(agent_set_paused, RID, p_agent, bool, p_paused) {
NavAgent *agent = agent_owner.getornull(p_agent);
ERR_FAIL_COND(agent == nullptr);
agent->set_paused(p_paused);
}
bool PandemoniumNavigationServer::agent_get_paused(RID p_agent) const {
NavAgent *agent = agent_owner.getornull(p_agent);
ERR_FAIL_COND_V(agent == nullptr, false);
return agent->get_paused();
}
COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_dist) { COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_dist) {
NavAgent *agent = agent_owner.getornull(p_agent); NavAgent *agent = agent_owner.getornull(p_agent);
ERR_FAIL_COND(agent == nullptr); ERR_FAIL_COND(agent == nullptr);
@ -888,6 +902,20 @@ RID PandemoniumNavigationServer::obstacle_get_map(RID p_obstacle) const {
return RID(); return RID();
} }
COMMAND_2(obstacle_set_paused, RID, p_obstacle, bool, p_paused) {
NavObstacle *obstacle = obstacle_owner.getornull(p_obstacle);
ERR_FAIL_COND(obstacle == nullptr);
obstacle->set_paused(p_paused);
}
bool PandemoniumNavigationServer::obstacle_get_paused(RID p_obstacle) const {
NavObstacle *obstacle = obstacle_owner.getornull(p_obstacle);
ERR_FAIL_COND_V(obstacle == nullptr, false);
return obstacle->get_paused();
}
COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height) { COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height) {
NavObstacle *obstacle = obstacle_owner.getornull(p_obstacle); NavObstacle *obstacle = obstacle_owner.getornull(p_obstacle);
ERR_FAIL_COND(obstacle == nullptr); ERR_FAIL_COND(obstacle == nullptr);

View File

@ -37,8 +37,8 @@
#include "nav_agent.h" #include "nav_agent.h"
#include "nav_link.h" #include "nav_link.h"
#include "nav_map.h" #include "nav_map.h"
#include "nav_region.h"
#include "nav_obstacle.h" #include "nav_obstacle.h"
#include "nav_region.h"
/// The commands are functions executed during the `sync` phase. /// The commands are functions executed during the `sync` phase.
@ -185,6 +185,8 @@ public:
virtual bool agent_get_use_3d_avoidance(RID p_agent) const; virtual bool agent_get_use_3d_avoidance(RID p_agent) const;
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map); COMMAND_2(agent_set_map, RID, p_agent, RID, p_map);
virtual RID agent_get_map(RID p_agent) const; virtual RID agent_get_map(RID p_agent) const;
COMMAND_2(agent_set_paused, RID, p_agent, bool, p_paused);
virtual bool agent_get_paused(RID p_agent) const;
COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_dist); COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_dist);
COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count); COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count);
COMMAND_2(agent_set_time_horizon_agents, RID, p_agent, real_t, p_time_horizon); COMMAND_2(agent_set_time_horizon_agents, RID, p_agent, real_t, p_time_horizon);
@ -205,6 +207,8 @@ public:
virtual RID obstacle_create(); virtual RID obstacle_create();
COMMAND_2(obstacle_set_map, RID, p_obstacle, RID, p_map); COMMAND_2(obstacle_set_map, RID, p_obstacle, RID, p_map);
virtual RID obstacle_get_map(RID p_obstacle) const; virtual RID obstacle_get_map(RID p_obstacle) const;
COMMAND_2(obstacle_set_paused, RID, p_obstacle, bool, p_paused);
virtual bool obstacle_get_paused(RID p_obstacle) const;
COMMAND_2(obstacle_set_position, RID, p_obstacle, Vector3, p_position); COMMAND_2(obstacle_set_position, RID, p_obstacle, Vector3, p_position);
COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height); COMMAND_2(obstacle_set_height, RID, p_obstacle, real_t, p_height);
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices); virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices);

View File

@ -77,6 +77,8 @@ public:
virtual RID agent_create() { return RID(); } virtual RID agent_create() { return RID(); }
virtual void agent_set_map(RID p_agent, RID p_map) {} virtual void agent_set_map(RID p_agent, RID p_map) {}
virtual RID agent_get_map(RID p_agent) const { return RID(); } virtual RID agent_get_map(RID p_agent) const { return RID(); }
virtual void agent_set_paused(RID p_agent, bool p_paused) {}
virtual bool agent_get_paused(RID p_agent) const { return false; }
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) {} virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) {}
virtual bool agent_get_avoidance_enabled(RID p_agent) const { return false; } virtual bool agent_get_avoidance_enabled(RID p_agent) const { return false; }
virtual void agent_set_neighbor_distance(RID p_agent, real_t p_dist) {} virtual void agent_set_neighbor_distance(RID p_agent, real_t p_dist) {}
@ -99,6 +101,8 @@ public:
virtual RID obstacle_create() { return RID(); } virtual RID obstacle_create() { return RID(); }
virtual void obstacle_set_map(RID p_obstacle, RID p_map) {} virtual void obstacle_set_map(RID p_obstacle, RID p_map) {}
virtual RID obstacle_get_map(RID p_obstacle) const { return RID(); } virtual RID obstacle_get_map(RID p_obstacle) const { return RID(); }
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) {}
virtual bool obstacle_get_paused(RID p_obstacle) const { return false; }
virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position) {} virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position) {}
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) {} virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) {}
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) {} virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) {}

View File

@ -79,6 +79,8 @@ public:
virtual RID agent_create() { return RID(); } virtual RID agent_create() { return RID(); }
virtual void agent_set_map(RID p_agent, RID p_map) {} virtual void agent_set_map(RID p_agent, RID p_map) {}
virtual RID agent_get_map(RID p_agent) const { return RID(); } virtual RID agent_get_map(RID p_agent) const { return RID(); }
virtual void agent_set_paused(RID p_agent, bool p_paused) {}
virtual bool agent_get_paused(RID p_agent) const { return false; }
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) {} virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) {}
virtual bool agent_get_avoidance_enabled(RID p_agent) const { return false; } virtual bool agent_get_avoidance_enabled(RID p_agent) const { return false; }
virtual void agent_set_use_3d_avoidance(RID p_agent, bool p_enabled) {} virtual void agent_set_use_3d_avoidance(RID p_agent, bool p_enabled) {}
@ -103,6 +105,8 @@ public:
virtual RID obstacle_create() { return RID(); } virtual RID obstacle_create() { return RID(); }
virtual void obstacle_set_map(RID p_obstacle, RID p_map) {} virtual void obstacle_set_map(RID p_obstacle, RID p_map) {}
virtual RID obstacle_get_map(RID p_obstacle) const { return RID(); } virtual RID obstacle_get_map(RID p_obstacle) const { return RID(); }
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) {}
virtual bool obstacle_get_paused(RID p_obstacle) const { return false; }
virtual void obstacle_set_height(RID p_obstacle, real_t p_height) {} virtual void obstacle_set_height(RID p_obstacle, real_t p_height) {}
virtual void obstacle_set_position(RID p_obstacle, Vector3 p_position) {} virtual void obstacle_set_position(RID p_obstacle, Vector3 p_position) {}
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) {} virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) {}

View File

@ -226,21 +226,13 @@ void NavigationAgent2D::_notification(int p_what) {
set_physics_process_internal(false); set_physics_process_internal(false);
} break; } break;
case NOTIFICATION_PAUSED: { case NOTIFICATION_PAUSED: {
if (agent_parent && !agent_parent->can_process()) { if (agent_parent) {
map_before_pause = Navigation2DServer::get_singleton()->agent_get_map(get_rid()); Navigation2DServer::get_singleton()->agent_set_paused(get_rid(), !agent_parent->can_process());
Navigation2DServer::get_singleton()->agent_set_map(get_rid(), RID());
} else if (agent_parent && agent_parent->can_process() && !(map_before_pause == RID())) {
Navigation2DServer::get_singleton()->agent_set_map(get_rid(), map_before_pause);
map_before_pause = RID();
} }
} break; } break;
case NOTIFICATION_UNPAUSED: { case NOTIFICATION_UNPAUSED: {
if (agent_parent && !agent_parent->can_process()) { if (agent_parent) {
map_before_pause = Navigation2DServer::get_singleton()->agent_get_map(get_rid()); Navigation2DServer::get_singleton()->agent_set_paused(get_rid(), !agent_parent->can_process());
Navigation2DServer::get_singleton()->agent_set_map(get_rid(), RID());
} else if (agent_parent && agent_parent->can_process() && !(map_before_pause == RID())) {
Navigation2DServer::get_singleton()->agent_set_map(get_rid(), map_before_pause);
map_before_pause = RID();
} }
} break; } break;
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {

View File

@ -46,7 +46,6 @@ class NavigationAgent2D : public Node {
Navigation2D *navigation; Navigation2D *navigation;
RID agent; RID agent;
RID map_before_pause;
RID map_override; RID map_override;
bool avoidance_enabled; bool avoidance_enabled;

View File

@ -112,6 +112,7 @@ void NavigationObstacle2D::_notification(int p_what) {
_update_map(map_before_pause); _update_map(map_before_pause);
map_before_pause = RID(); map_before_pause = RID();
} }
Navigation2DServer::get_singleton()->obstacle_set_paused(obstacle, !can_process());
} break; } break;
case NOTIFICATION_UNPAUSED: { case NOTIFICATION_UNPAUSED: {
if (!can_process()) { if (!can_process()) {
@ -121,6 +122,7 @@ void NavigationObstacle2D::_notification(int p_what) {
_update_map(map_before_pause); _update_map(map_before_pause);
map_before_pause = RID(); map_before_pause = RID();
} }
Navigation2DServer::get_singleton()->obstacle_set_paused(obstacle, !can_process());
} break; } break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (is_inside_tree()) { if (is_inside_tree()) {

View File

@ -249,21 +249,13 @@ void NavigationAgent::_notification(int p_what) {
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED
} break; } break;
case NOTIFICATION_PAUSED: { case NOTIFICATION_PAUSED: {
if (agent_parent && !agent_parent->can_process()) { if (agent_parent) {
map_before_pause = NavigationServer::get_singleton()->agent_get_map(get_rid()); NavigationServer::get_singleton()->agent_set_paused(get_rid(), !agent_parent->can_process());
NavigationServer::get_singleton()->agent_set_map(get_rid(), RID());
} else if (agent_parent && agent_parent->can_process() && !(map_before_pause == RID())) {
NavigationServer::get_singleton()->agent_set_map(get_rid(), map_before_pause);
map_before_pause = RID();
} }
} break; } break;
case NOTIFICATION_UNPAUSED: { case NOTIFICATION_UNPAUSED: {
if (agent_parent && !agent_parent->can_process()) { if (agent_parent) {
map_before_pause = NavigationServer::get_singleton()->agent_get_map(get_rid()); NavigationServer::get_singleton()->agent_set_paused(get_rid(), !agent_parent->can_process());
NavigationServer::get_singleton()->agent_set_map(get_rid(), RID());
} else if (agent_parent && agent_parent->can_process() && !(map_before_pause == RID())) {
NavigationServer::get_singleton()->agent_set_map(get_rid(), map_before_pause);
map_before_pause = RID();
} }
} break; } break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {

View File

@ -49,7 +49,6 @@ class NavigationAgent : public Node {
Navigation *navigation; Navigation *navigation;
RID agent; RID agent;
RID map_before_pause;
RID map_override; RID map_override;
bool avoidance_enabled; bool avoidance_enabled;

View File

@ -131,6 +131,7 @@ void NavigationObstacle::_notification(int p_what) {
_update_map(map_before_pause); _update_map(map_before_pause);
map_before_pause = RID(); map_before_pause = RID();
} }
NavigationServer::get_singleton()->obstacle_set_paused(obstacle, !can_process());
} break; } break;
case NOTIFICATION_UNPAUSED: { case NOTIFICATION_UNPAUSED: {
if (!can_process()) { if (!can_process()) {
@ -140,6 +141,7 @@ void NavigationObstacle::_notification(int p_what) {
_update_map(map_before_pause); _update_map(map_before_pause);
map_before_pause = RID(); map_before_pause = RID();
} }
NavigationServer::get_singleton()->obstacle_set_paused(obstacle, !can_process());
} break; } break;
case NOTIFICATION_EXIT_TREE: { case NOTIFICATION_EXIT_TREE: {
set_navigation(nullptr); set_navigation(nullptr);

View File

@ -106,6 +106,8 @@ void Navigation2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("agent_get_avoidance_enabled", "agent"), &Navigation2DServer::agent_get_avoidance_enabled); ClassDB::bind_method(D_METHOD("agent_get_avoidance_enabled", "agent"), &Navigation2DServer::agent_get_avoidance_enabled);
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &Navigation2DServer::agent_set_map); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &Navigation2DServer::agent_set_map);
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &Navigation2DServer::agent_get_map); ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &Navigation2DServer::agent_get_map);
ClassDB::bind_method(D_METHOD("agent_set_paused", "agent", "paused"), &Navigation2DServer::agent_set_paused);
ClassDB::bind_method(D_METHOD("agent_get_paused", "agent"), &Navigation2DServer::agent_get_paused);
ClassDB::bind_method(D_METHOD("agent_set_neighbor_distance", "agent", "dist"), &Navigation2DServer::agent_set_neighbor_distance); ClassDB::bind_method(D_METHOD("agent_set_neighbor_distance", "agent", "dist"), &Navigation2DServer::agent_set_neighbor_distance);
ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &Navigation2DServer::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &Navigation2DServer::agent_set_max_neighbors);
ClassDB::bind_method(D_METHOD("agent_set_time_horizon_agents", "agent", "time_horizon"), &Navigation2DServer::agent_set_time_horizon_agents); ClassDB::bind_method(D_METHOD("agent_set_time_horizon_agents", "agent", "time_horizon"), &Navigation2DServer::agent_set_time_horizon_agents);
@ -124,6 +126,8 @@ void Navigation2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("obstacle_create"), &Navigation2DServer::obstacle_create); ClassDB::bind_method(D_METHOD("obstacle_create"), &Navigation2DServer::obstacle_create);
ClassDB::bind_method(D_METHOD("obstacle_set_map", "obstacle", "map"), &Navigation2DServer::obstacle_set_map); ClassDB::bind_method(D_METHOD("obstacle_set_map", "obstacle", "map"), &Navigation2DServer::obstacle_set_map);
ClassDB::bind_method(D_METHOD("obstacle_get_map", "obstacle"), &Navigation2DServer::obstacle_get_map); ClassDB::bind_method(D_METHOD("obstacle_get_map", "obstacle"), &Navigation2DServer::obstacle_get_map);
ClassDB::bind_method(D_METHOD("obstacle_set_paused", "obstacle", "paused"), &Navigation2DServer::obstacle_set_paused);
ClassDB::bind_method(D_METHOD("obstacle_get_paused", "obstacle"), &Navigation2DServer::obstacle_get_paused);
ClassDB::bind_method(D_METHOD("obstacle_set_position", "obstacle", "position"), &Navigation2DServer::obstacle_set_position); ClassDB::bind_method(D_METHOD("obstacle_set_position", "obstacle", "position"), &Navigation2DServer::obstacle_set_position);
ClassDB::bind_method(D_METHOD("obstacle_set_vertices", "obstacle", "vertices"), &Navigation2DServer::obstacle_set_vertices); ClassDB::bind_method(D_METHOD("obstacle_set_vertices", "obstacle", "vertices"), &Navigation2DServer::obstacle_set_vertices);
ClassDB::bind_method(D_METHOD("obstacle_set_avoidance_layers", "obstacle", "layers"), &Navigation2DServer::obstacle_set_avoidance_layers); ClassDB::bind_method(D_METHOD("obstacle_set_avoidance_layers", "obstacle", "layers"), &Navigation2DServer::obstacle_set_avoidance_layers);

View File

@ -183,6 +183,9 @@ public:
virtual void agent_set_map(RID p_agent, RID p_map) = 0; virtual void agent_set_map(RID p_agent, RID p_map) = 0;
virtual RID agent_get_map(RID p_agent) const = 0; virtual RID agent_get_map(RID p_agent) const = 0;
virtual void agent_set_paused(RID p_agent, bool p_paused) = 0;
virtual bool agent_get_paused(RID p_agent) const = 0;
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) = 0; virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) = 0;
virtual bool agent_get_avoidance_enabled(RID p_agent) const = 0; virtual bool agent_get_avoidance_enabled(RID p_agent) const = 0;
@ -246,6 +249,10 @@ public:
virtual RID obstacle_create() = 0; virtual RID obstacle_create() = 0;
virtual void obstacle_set_map(RID p_obstacle, RID p_map) = 0; virtual void obstacle_set_map(RID p_obstacle, RID p_map) = 0;
virtual RID obstacle_get_map(RID p_obstacle) const = 0; virtual RID obstacle_get_map(RID p_obstacle) const = 0;
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) = 0;
virtual bool obstacle_get_paused(RID p_obstacle) const = 0;
virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position) = 0; virtual void obstacle_set_position(RID p_obstacle, Vector2 p_position) = 0;
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) = 0; virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector2> &p_vertices) = 0;
virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) = 0; virtual void obstacle_set_avoidance_layers(RID p_obstacle, uint32_t p_layers) = 0;

View File

@ -131,6 +131,8 @@ void NavigationServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer::agent_set_map); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer::agent_set_map);
ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer::agent_get_map); ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer::agent_get_map);
ClassDB::bind_method(D_METHOD("agent_set_paused", "agent", "paused"), &NavigationServer::agent_set_paused);
ClassDB::bind_method(D_METHOD("agent_get_paused", "agent"), &NavigationServer::agent_get_paused);
ClassDB::bind_method(D_METHOD("agent_set_neighbor_distance", "agent", "dist"), &NavigationServer::agent_set_neighbor_distance); ClassDB::bind_method(D_METHOD("agent_set_neighbor_distance", "agent", "dist"), &NavigationServer::agent_set_neighbor_distance);
ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &NavigationServer::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &NavigationServer::agent_set_max_neighbors);
ClassDB::bind_method(D_METHOD("agent_set_time_horizon_agents", "agent", "time_horizon"), &NavigationServer::agent_set_time_horizon_agents); ClassDB::bind_method(D_METHOD("agent_set_time_horizon_agents", "agent", "time_horizon"), &NavigationServer::agent_set_time_horizon_agents);
@ -151,6 +153,8 @@ void NavigationServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("obstacle_create"), &NavigationServer::obstacle_create); ClassDB::bind_method(D_METHOD("obstacle_create"), &NavigationServer::obstacle_create);
ClassDB::bind_method(D_METHOD("obstacle_set_map", "obstacle", "map"), &NavigationServer::obstacle_set_map); ClassDB::bind_method(D_METHOD("obstacle_set_map", "obstacle", "map"), &NavigationServer::obstacle_set_map);
ClassDB::bind_method(D_METHOD("obstacle_get_map", "obstacle"), &NavigationServer::obstacle_get_map); ClassDB::bind_method(D_METHOD("obstacle_get_map", "obstacle"), &NavigationServer::obstacle_get_map);
ClassDB::bind_method(D_METHOD("obstacle_set_paused", "obstacle", "paused"), &NavigationServer::obstacle_set_paused);
ClassDB::bind_method(D_METHOD("obstacle_get_paused", "obstacle"), &NavigationServer::obstacle_get_paused);
ClassDB::bind_method(D_METHOD("obstacle_set_height", "obstacle", "height"), &NavigationServer::obstacle_set_height); ClassDB::bind_method(D_METHOD("obstacle_set_height", "obstacle", "height"), &NavigationServer::obstacle_set_height);
ClassDB::bind_method(D_METHOD("obstacle_set_position", "obstacle", "position"), &NavigationServer::obstacle_set_position); ClassDB::bind_method(D_METHOD("obstacle_set_position", "obstacle", "position"), &NavigationServer::obstacle_set_position);
ClassDB::bind_method(D_METHOD("obstacle_set_vertices", "obstacle", "vertices"), &NavigationServer::obstacle_set_vertices); ClassDB::bind_method(D_METHOD("obstacle_set_vertices", "obstacle", "vertices"), &NavigationServer::obstacle_set_vertices);

View File

@ -199,6 +199,9 @@ public:
virtual void agent_set_map(RID p_agent, RID p_map) = 0; virtual void agent_set_map(RID p_agent, RID p_map) = 0;
virtual RID agent_get_map(RID p_agent) const = 0; virtual RID agent_get_map(RID p_agent) const = 0;
virtual void agent_set_paused(RID p_agent, bool p_paused) = 0;
virtual bool agent_get_paused(RID p_agent) const = 0;
virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) = 0; virtual void agent_set_avoidance_enabled(RID p_agent, bool p_enabled) = 0;
virtual bool agent_get_avoidance_enabled(RID p_agent) const = 0; virtual bool agent_get_avoidance_enabled(RID p_agent) const = 0;
@ -265,6 +268,10 @@ public:
virtual RID obstacle_create() = 0; virtual RID obstacle_create() = 0;
virtual void obstacle_set_map(RID p_obstacle, RID p_map) = 0; virtual void obstacle_set_map(RID p_obstacle, RID p_map) = 0;
virtual RID obstacle_get_map(RID p_obstacle) const = 0; virtual RID obstacle_get_map(RID p_obstacle) const = 0;
virtual void obstacle_set_paused(RID p_obstacle, bool p_paused) = 0;
virtual bool obstacle_get_paused(RID p_obstacle) const = 0;
virtual void obstacle_set_height(RID p_obstacle, real_t p_height) = 0; virtual void obstacle_set_height(RID p_obstacle, real_t p_height) = 0;
virtual void obstacle_set_position(RID p_obstacle, Vector3 p_position) = 0; virtual void obstacle_set_position(RID p_obstacle, Vector3 p_position) = 0;
virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) = 0; virtual void obstacle_set_vertices(RID p_obstacle, const Vector<Vector3> &p_vertices) = 0;