diff --git a/modules/navigation/pandemonium_navigation_server.cpp b/modules/navigation/pandemonium_navigation_server.cpp index e239cfd33..2147a825f 100644 --- a/modules/navigation/pandemonium_navigation_server.cpp +++ b/modules/navigation/pandemonium_navigation_server.cpp @@ -275,13 +275,23 @@ Array PandemoniumNavigationServer::map_get_agents(RID p_map) const { RID PandemoniumNavigationServer::region_get_map(RID p_region) const { NavRegion *region = region_owner.getornull(p_region); ERR_FAIL_COND_V(region == nullptr, RID()); - return region->get_map()->get_self(); + + if (region->get_map()) { + return region->get_map()->get_self(); + } + + return RID(); } RID PandemoniumNavigationServer::agent_get_map(RID p_agent) const { RvoAgent *agent = agent_owner.getornull(p_agent); ERR_FAIL_COND_V(agent == nullptr, RID()); - return agent->get_map()->get_self(); + + if (agent->get_map()) { + return agent->get_map()->get_self(); + } + + return RID(); } RID PandemoniumNavigationServer::region_create() const { diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index e64bcb973..835aa662f 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -115,6 +115,24 @@ void NavigationAgent2D::_notification(int p_what) { set_physics_process_internal(true); } break; + case NOTIFICATION_PAUSED: { + if (agent_parent && !agent_parent->can_process()) { + map_before_pause = Navigation2DServer::get_singleton()->agent_get_map(get_rid()); + 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; + case NOTIFICATION_UNPAUSED: { + if (agent_parent && !agent_parent->can_process()) { + map_before_pause = Navigation2DServer::get_singleton()->agent_get_map(get_rid()); + 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; case NOTIFICATION_EXIT_TREE: { agent_parent = nullptr; set_navigation(nullptr); diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 1abe5c4f0..8ee2c3c53 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -42,6 +42,7 @@ class NavigationAgent2D : public Node { Navigation2D *navigation; RID agent; + RID map_before_pause; real_t target_desired_distance; real_t radius; diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index 8c1328797..452e4cf11 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -95,6 +95,24 @@ void NavigationObstacle2D::_notification(int p_what) { case NOTIFICATION_UNPARENTED: { parent_node2d = nullptr; } break; + case NOTIFICATION_PAUSED: { + if (parent_node2d && !parent_node2d->can_process()) { + map_before_pause = Navigation2DServer::get_singleton()->agent_get_map(get_rid()); + Navigation2DServer::get_singleton()->agent_set_map(get_rid(), RID()); + } else if (parent_node2d && parent_node2d->can_process() && !(map_before_pause == RID())) { + Navigation2DServer::get_singleton()->agent_set_map(get_rid(), map_before_pause); + map_before_pause = RID(); + } + } break; + case NOTIFICATION_UNPAUSED: { + if (parent_node2d && !parent_node2d->can_process()) { + map_before_pause = Navigation2DServer::get_singleton()->agent_get_map(get_rid()); + Navigation2DServer::get_singleton()->agent_set_map(get_rid(), RID()); + } else if (parent_node2d && parent_node2d->can_process() && !(map_before_pause == RID())) { + Navigation2DServer::get_singleton()->agent_set_map(get_rid(), map_before_pause); + map_before_pause = RID(); + } + } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (parent_node2d && parent_node2d->is_inside_tree()) { Navigation2DServer::get_singleton()->agent_set_position(agent, parent_node2d->get_global_transform().get_origin()); diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index df650d3fc..76d86bfef 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -42,6 +42,8 @@ class NavigationObstacle2D : public Node { Node2D *parent_node2d = nullptr; RID agent; + RID map_before_pause; + bool estimate_radius = true; real_t radius = 1.0; diff --git a/scene/3d/navigation_agent.cpp b/scene/3d/navigation_agent.cpp index b67fd24a5..b620f1bd8 100644 --- a/scene/3d/navigation_agent.cpp +++ b/scene/3d/navigation_agent.cpp @@ -131,6 +131,24 @@ void NavigationAgent::_notification(int p_what) { // the navigation map may not be ready at that time. This fixes issues with taking the agent out of the scene tree. request_ready(); } break; + case NOTIFICATION_PAUSED: { + if (agent_parent && !agent_parent->can_process()) { + map_before_pause = NavigationServer::get_singleton()->agent_get_map(get_rid()); + 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; + case NOTIFICATION_UNPAUSED: { + if (agent_parent && !agent_parent->can_process()) { + map_before_pause = NavigationServer::get_singleton()->agent_get_map(get_rid()); + 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; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (agent_parent) { NavigationServer::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin); diff --git a/scene/3d/navigation_agent.h b/scene/3d/navigation_agent.h index 68a5608d7..ab7e5f0bc 100644 --- a/scene/3d/navigation_agent.h +++ b/scene/3d/navigation_agent.h @@ -43,6 +43,7 @@ class NavigationAgent : public Node { Navigation *navigation; RID agent; + RID map_before_pause; real_t target_desired_distance; real_t radius; diff --git a/scene/3d/navigation_obstacle.cpp b/scene/3d/navigation_obstacle.cpp index a13754cea..8c7875835 100644 --- a/scene/3d/navigation_obstacle.cpp +++ b/scene/3d/navigation_obstacle.cpp @@ -83,6 +83,24 @@ void NavigationObstacle::_notification(int p_what) { set_physics_process_internal(true); } break; + case NOTIFICATION_PAUSED: { + if (parent_spatial && !parent_spatial->can_process()) { + map_before_pause = NavigationServer::get_singleton()->agent_get_map(get_rid()); + NavigationServer::get_singleton()->agent_set_map(get_rid(), RID()); + } else if (parent_spatial && parent_spatial->can_process() && !(map_before_pause == RID())) { + NavigationServer::get_singleton()->agent_set_map(get_rid(), map_before_pause); + map_before_pause = RID(); + } + } break; + case NOTIFICATION_UNPAUSED: { + if (parent_spatial && !parent_spatial->can_process()) { + map_before_pause = NavigationServer::get_singleton()->agent_get_map(get_rid()); + NavigationServer::get_singleton()->agent_set_map(get_rid(), RID()); + } else if (parent_spatial && parent_spatial->can_process() && !(map_before_pause == RID())) { + NavigationServer::get_singleton()->agent_set_map(get_rid(), map_before_pause); + map_before_pause = RID(); + } + } break; case NOTIFICATION_EXIT_TREE: { set_navigation(nullptr); set_physics_process_internal(false); diff --git a/scene/3d/navigation_obstacle.h b/scene/3d/navigation_obstacle.h index ccbec0f63..f199794aa 100644 --- a/scene/3d/navigation_obstacle.h +++ b/scene/3d/navigation_obstacle.h @@ -42,6 +42,8 @@ class NavigationObstacle : public Node { Navigation *navigation; RID agent; + RID map_before_pause; + bool estimate_radius = true; real_t radius = 1.0;