Fix NavigationObstacle 2D/3D (re)parent issues
Fixes (re)parent issues with NavigationObstacle 2D and 3D (same as NavigationAgents). Also adds the option from NavigationAgents to override the default navigation map.
This commit is contained in:
parent
e9e9e92e48
commit
5162d9ac8b
|
@ -10,12 +10,25 @@
|
|||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="get_navigation_map" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
Returns the [RID] of the navigation map for this NavigationObstacle node. This function returns always the map set on the NavigationObstacle node and not the map of the abstract agent on the NavigationServer. If the agent map is changed directly with the NavigationServer API the NavigationObstacle node will not be aware of the map change. Use [method set_navigation_map] to change the navigation map for the NavigationObstacle and also update the agent on the NavigationServer.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_rid" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
Returns the [RID] of this obstacle on the [NavigationServer2D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_navigation_map">
|
||||
<return type="void" />
|
||||
<param index="0" name="navigation_map" type="RID" />
|
||||
<description>
|
||||
Sets the [RID] of the navigation map this NavigationObstacle node should use and also updates the [code]agent[/code] on the NavigationServer.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="estimate_radius" type="bool" setter="set_estimate_radius" getter="is_radius_estimated" default="true">
|
||||
|
|
|
@ -10,12 +10,25 @@
|
|||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="get_navigation_map" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
Returns the [RID] of the navigation map for this NavigationObstacle node. This function returns always the map set on the NavigationObstacle node and not the map of the abstract agent on the NavigationServer. If the agent map is changed directly with the NavigationServer API the NavigationObstacle node will not be aware of the map change. Use [method set_navigation_map] to change the navigation map for the NavigationObstacle and also update the agent on the NavigationServer.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_rid" qualifiers="const">
|
||||
<return type="RID" />
|
||||
<description>
|
||||
Returns the [RID] of this obstacle on the [NavigationServer3D].
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_navigation_map">
|
||||
<return type="void" />
|
||||
<param index="0" name="navigation_map" type="RID" />
|
||||
<description>
|
||||
Sets the [RID] of the navigation map this NavigationObstacle node should use and also updates the [code]agent[/code] on the NavigationServer.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="estimate_radius" type="bool" setter="set_estimate_radius" getter="is_radius_estimated" default="true">
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
void NavigationObstacle2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationObstacle2D::get_rid);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationObstacle2D::set_navigation_map);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationObstacle2D::get_navigation_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_estimate_radius", "estimate_radius"), &NavigationObstacle2D::set_estimate_radius);
|
||||
ClassDB::bind_method(D_METHOD("is_radius_estimated"), &NavigationObstacle2D::is_radius_estimated);
|
||||
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationObstacle2D::set_radius);
|
||||
|
@ -57,28 +60,26 @@ void NavigationObstacle2D::_validate_property(PropertyInfo &p_property) const {
|
|||
|
||||
void NavigationObstacle2D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
parent_node2d = Object::cast_to<Node2D>(get_parent());
|
||||
reevaluate_agent_radius();
|
||||
if (parent_node2d != nullptr) {
|
||||
// place agent on navigation map first or else the RVO agent callback creation fails silently later
|
||||
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map());
|
||||
}
|
||||
case NOTIFICATION_POST_ENTER_TREE: {
|
||||
set_agent_parent(get_parent());
|
||||
set_physics_process_internal(true);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
parent_node2d = nullptr;
|
||||
set_agent_parent(nullptr);
|
||||
set_physics_process_internal(false);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_PARENTED: {
|
||||
parent_node2d = Object::cast_to<Node2D>(get_parent());
|
||||
reevaluate_agent_radius();
|
||||
if (is_inside_tree() && (get_parent() != parent_node2d)) {
|
||||
set_agent_parent(get_parent());
|
||||
set_physics_process_internal(true);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_UNPARENTED: {
|
||||
parent_node2d = nullptr;
|
||||
set_agent_parent(nullptr);
|
||||
set_physics_process_internal(false);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_PAUSED: {
|
||||
|
@ -182,6 +183,35 @@ real_t NavigationObstacle2D::estimate_agent_radius() const {
|
|||
return 1.0; // Never a 0 radius
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_agent_parent(Node *p_agent_parent) {
|
||||
if (Object::cast_to<Node2D>(p_agent_parent) != nullptr) {
|
||||
parent_node2d = Object::cast_to<Node2D>(p_agent_parent);
|
||||
if (map_override.is_valid()) {
|
||||
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), map_override);
|
||||
} else {
|
||||
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map());
|
||||
}
|
||||
reevaluate_agent_radius();
|
||||
} else {
|
||||
parent_node2d = nullptr;
|
||||
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), RID());
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_navigation_map(RID p_navigation_map) {
|
||||
map_override = p_navigation_map;
|
||||
NavigationServer2D::get_singleton()->agent_set_map(agent, map_override);
|
||||
}
|
||||
|
||||
RID NavigationObstacle2D::get_navigation_map() const {
|
||||
if (map_override.is_valid()) {
|
||||
return map_override;
|
||||
} else if (parent_node2d != nullptr) {
|
||||
return parent_node2d->get_world_2d()->get_navigation_map();
|
||||
}
|
||||
return RID();
|
||||
}
|
||||
|
||||
void NavigationObstacle2D::set_estimate_radius(bool p_estimate_radius) {
|
||||
estimate_radius = p_estimate_radius;
|
||||
notify_property_list_changed();
|
||||
|
|
|
@ -38,8 +38,10 @@ class NavigationObstacle2D : public Node {
|
|||
GDCLASS(NavigationObstacle2D, Node);
|
||||
|
||||
Node2D *parent_node2d = nullptr;
|
||||
|
||||
RID agent;
|
||||
RID map_before_pause;
|
||||
RID map_override;
|
||||
|
||||
bool estimate_radius = true;
|
||||
real_t radius = 1.0;
|
||||
|
@ -57,6 +59,11 @@ public:
|
|||
return agent;
|
||||
}
|
||||
|
||||
void set_agent_parent(Node *p_agent_parent);
|
||||
|
||||
void set_navigation_map(RID p_navigation_map);
|
||||
RID get_navigation_map() const;
|
||||
|
||||
void set_estimate_radius(bool p_estimate_radius);
|
||||
bool is_radius_estimated() const {
|
||||
return estimate_radius;
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
void NavigationObstacle3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_rid"), &NavigationObstacle3D::get_rid);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_navigation_map", "navigation_map"), &NavigationObstacle3D::set_navigation_map);
|
||||
ClassDB::bind_method(D_METHOD("get_navigation_map"), &NavigationObstacle3D::get_navigation_map);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_estimate_radius", "estimate_radius"), &NavigationObstacle3D::set_estimate_radius);
|
||||
ClassDB::bind_method(D_METHOD("is_radius_estimated"), &NavigationObstacle3D::is_radius_estimated);
|
||||
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationObstacle3D::set_radius);
|
||||
|
@ -56,28 +59,26 @@ void NavigationObstacle3D::_validate_property(PropertyInfo &p_property) const {
|
|||
|
||||
void NavigationObstacle3D::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
parent_node3d = Object::cast_to<Node3D>(get_parent());
|
||||
reevaluate_agent_radius();
|
||||
if (parent_node3d != nullptr) {
|
||||
// place agent on navigation map first or else the RVO agent callback creation fails silently later
|
||||
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), parent_node3d->get_world_3d()->get_navigation_map());
|
||||
}
|
||||
case NOTIFICATION_POST_ENTER_TREE: {
|
||||
set_agent_parent(get_parent());
|
||||
set_physics_process_internal(true);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
parent_node3d = nullptr;
|
||||
set_agent_parent(nullptr);
|
||||
set_physics_process_internal(false);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_PARENTED: {
|
||||
parent_node3d = Object::cast_to<Node3D>(get_parent());
|
||||
reevaluate_agent_radius();
|
||||
if (is_inside_tree() && (get_parent() != parent_node3d)) {
|
||||
set_agent_parent(get_parent());
|
||||
set_physics_process_internal(true);
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_UNPARENTED: {
|
||||
parent_node3d = nullptr;
|
||||
set_agent_parent(nullptr);
|
||||
set_physics_process_internal(false);
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_PAUSED: {
|
||||
|
@ -189,6 +190,35 @@ real_t NavigationObstacle3D::estimate_agent_radius() const {
|
|||
return 1.0; // Never a 0 radius
|
||||
}
|
||||
|
||||
void NavigationObstacle3D::set_agent_parent(Node *p_agent_parent) {
|
||||
if (Object::cast_to<Node3D>(p_agent_parent) != nullptr) {
|
||||
parent_node3d = Object::cast_to<Node3D>(p_agent_parent);
|
||||
if (map_override.is_valid()) {
|
||||
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), map_override);
|
||||
} else {
|
||||
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), parent_node3d->get_world_3d()->get_navigation_map());
|
||||
}
|
||||
reevaluate_agent_radius();
|
||||
} else {
|
||||
parent_node3d = nullptr;
|
||||
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), RID());
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationObstacle3D::set_navigation_map(RID p_navigation_map) {
|
||||
map_override = p_navigation_map;
|
||||
NavigationServer3D::get_singleton()->agent_set_map(agent, map_override);
|
||||
}
|
||||
|
||||
RID NavigationObstacle3D::get_navigation_map() const {
|
||||
if (map_override.is_valid()) {
|
||||
return map_override;
|
||||
} else if (parent_node3d != nullptr) {
|
||||
return parent_node3d->get_world_3d()->get_navigation_map();
|
||||
}
|
||||
return RID();
|
||||
}
|
||||
|
||||
void NavigationObstacle3D::set_estimate_radius(bool p_estimate_radius) {
|
||||
estimate_radius = p_estimate_radius;
|
||||
notify_property_list_changed();
|
||||
|
|
|
@ -37,8 +37,10 @@ class NavigationObstacle3D : public Node {
|
|||
GDCLASS(NavigationObstacle3D, Node);
|
||||
|
||||
Node3D *parent_node3d = nullptr;
|
||||
|
||||
RID agent;
|
||||
RID map_before_pause;
|
||||
RID map_override;
|
||||
|
||||
bool estimate_radius = true;
|
||||
real_t radius = 1.0;
|
||||
|
@ -56,6 +58,11 @@ public:
|
|||
return agent;
|
||||
}
|
||||
|
||||
void set_agent_parent(Node *p_agent_parent);
|
||||
|
||||
void set_navigation_map(RID p_navigation_map);
|
||||
RID get_navigation_map() const;
|
||||
|
||||
void set_estimate_radius(bool p_estimate_radius);
|
||||
bool is_radius_estimated() const {
|
||||
return estimate_radius;
|
||||
|
|
Loading…
Reference in New Issue