diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/area_2d.cpp | 12 | ||||
-rw-r--r-- | scene/2d/navigation_obstacle_2d.cpp | 65 | ||||
-rw-r--r-- | scene/2d/navigation_obstacle_2d.h | 17 | ||||
-rw-r--r-- | scene/2d/polygon_2d.cpp | 7 |
4 files changed, 79 insertions, 22 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index fff9c47d4d..75a1723e04 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -369,12 +369,11 @@ void Area2D::set_monitoring(bool p_enable) { monitoring = p_enable; if (monitoring) { - PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout); - PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout); - + PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), callable_mp(this, &Area2D::_body_inout)); + PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), callable_mp(this, &Area2D::_area_inout)); } else { - PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), nullptr, StringName()); - PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), nullptr, StringName()); + PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), Callable()); + PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), Callable()); _clear_monitoring(); } } @@ -530,9 +529,6 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area2D::set_audio_bus_override); ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area2D::is_overriding_audio_bus); - ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout); - ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"))); diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index 0a105826c0..4cfc7fe89e 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -34,19 +34,41 @@ #include "servers/navigation_server_2d.h" void NavigationObstacle2D::_bind_methods() { + 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); + ClassDB::bind_method(D_METHOD("get_radius"), &NavigationObstacle2D::get_radius); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "estimate_radius"), "set_estimate_radius", "is_radius_estimated"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.01,500,0.01"), "set_radius", "get_radius"); +} + +void NavigationObstacle2D::_validate_property(PropertyInfo &p_property) const { + if (p_property.name == "radius") { + if (estimate_radius) { + p_property.usage = PROPERTY_USAGE_NOEDITOR; + } + } } void NavigationObstacle2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { + initialize_agent(); + parent_node2d = Object::cast_to<Node2D>(get_parent()); + 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()); + } set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { + parent_node2d = nullptr; set_physics_process_internal(false); } break; case NOTIFICATION_PARENTED: { parent_node2d = Object::cast_to<Node2D>(get_parent()); - update_agent_shape(); + reevaluate_agent_radius(); } break; case NOTIFICATION_UNPARENTED: { parent_node2d = nullptr; @@ -78,7 +100,22 @@ TypedArray<String> NavigationObstacle2D::get_configuration_warnings() const { return warnings; } -void NavigationObstacle2D::update_agent_shape() { +void NavigationObstacle2D::initialize_agent() { + NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); + NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0); + NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0); + NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0); +} + +void NavigationObstacle2D::reevaluate_agent_radius() { + if (!estimate_radius) { + NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); + } else if (parent_node2d) { + NavigationServer2D::get_singleton()->agent_set_radius(agent, estimate_agent_radius()); + } +} + +real_t NavigationObstacle2D::estimate_agent_radius() const { if (parent_node2d) { // Estimate the radius of this physics body real_t radius = 0.0; @@ -101,15 +138,21 @@ void NavigationObstacle2D::update_agent_shape() { Vector2 s = parent_node2d->get_global_scale(); radius *= MAX(s.x, s.y); - if (radius == 0.0) { - radius = 1.0; // Never a 0 radius + if (radius > 0.0) { + return radius; } - - // Initialize the Agent as an object - NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); - NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, 0); - NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, 0.0); - NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); - NavigationServer2D::get_singleton()->agent_set_max_speed(agent, 0.0); } + return 1.0; // Never a 0 radius +} + +void NavigationObstacle2D::set_estimate_radius(bool p_estimate_radius) { + estimate_radius = p_estimate_radius; + notify_property_list_changed(); + reevaluate_agent_radius(); +} + +void NavigationObstacle2D::set_radius(real_t p_radius) { + ERR_FAIL_COND_MSG(p_radius <= 0.0, "Radius must be greater than 0."); + radius = p_radius; + reevaluate_agent_radius(); } diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h index 9cffc2c0c3..a5603f059f 100644 --- a/scene/2d/navigation_obstacle_2d.h +++ b/scene/2d/navigation_obstacle_2d.h @@ -40,8 +40,12 @@ class NavigationObstacle2D : public Node { Node2D *parent_node2d = nullptr; RID agent; + bool estimate_radius = true; + real_t radius = 1.0; + protected: static void _bind_methods(); + void _validate_property(PropertyInfo &p_property) const override; void _notification(int p_what); public: @@ -52,10 +56,21 @@ public: return agent; } + void set_estimate_radius(bool p_estimate_radius); + bool is_radius_estimated() const { + return estimate_radius; + } + void set_radius(real_t p_radius); + real_t get_radius() const { + return radius; + } + TypedArray<String> get_configuration_warnings() const override; private: - void update_agent_shape(); + void initialize_agent(); + void reevaluate_agent_radius(); + real_t estimate_agent_radius() const; }; #endif diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 7366be5a7d..510746c53f 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -554,7 +554,9 @@ void Polygon2D::set_bone_path(int p_index, const NodePath &p_path) { Array Polygon2D::_get_bones() const { Array bones; for (int i = 0; i < get_bone_count(); i++) { - bones.push_back(get_bone_path(i)); + // Convert path property to String to avoid errors due to invalid node path in editor, + // because it's relative to the Skeleton2D node and not Polygon2D. + bones.push_back(String(get_bone_path(i))); bones.push_back(get_bone_weights(i)); } return bones; @@ -564,7 +566,8 @@ void Polygon2D::_set_bones(const Array &p_bones) { ERR_FAIL_COND(p_bones.size() & 1); clear_bones(); for (int i = 0; i < p_bones.size(); i += 2) { - add_bone(p_bones[i], p_bones[i + 1]); + // Convert back from String to NodePath. + add_bone(NodePath(p_bones[i]), p_bones[i + 1]); } } |