diff options
Diffstat (limited to 'scene/2d')
26 files changed, 422 insertions, 87 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index f80da6e9ab..a37fabf21f 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -51,13 +51,13 @@ bool Area2D::is_gravity_a_point() const { return gravity_is_point; } -void Area2D::set_gravity_point_distance_scale(real_t p_scale) { - gravity_distance_scale = p_scale; - PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale); +void Area2D::set_gravity_point_unit_distance(real_t p_scale) { + gravity_point_unit_distance = p_scale; + PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_UNIT_DISTANCE, p_scale); } -real_t Area2D::get_gravity_point_distance_scale() const { - return gravity_distance_scale; +real_t Area2D::get_gravity_point_unit_distance() const { + return gravity_point_unit_distance; } void Area2D::set_gravity_point_center(const Vector2 &p_center) { @@ -557,8 +557,8 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gravity_is_point", "enable"), &Area2D::set_gravity_is_point); ClassDB::bind_method(D_METHOD("is_gravity_a_point"), &Area2D::is_gravity_a_point); - ClassDB::bind_method(D_METHOD("set_gravity_point_distance_scale", "distance_scale"), &Area2D::set_gravity_point_distance_scale); - ClassDB::bind_method(D_METHOD("get_gravity_point_distance_scale"), &Area2D::get_gravity_point_distance_scale); + ClassDB::bind_method(D_METHOD("set_gravity_point_unit_distance", "distance_scale"), &Area2D::set_gravity_point_unit_distance); + ClassDB::bind_method(D_METHOD("get_gravity_point_unit_distance"), &Area2D::get_gravity_point_unit_distance); ClassDB::bind_method(D_METHOD("set_gravity_point_center", "center"), &Area2D::set_gravity_point_center); ClassDB::bind_method(D_METHOD("get_gravity_point_center"), &Area2D::get_gravity_point_center); @@ -622,7 +622,7 @@ void Area2D::_bind_methods() { ADD_GROUP("Gravity", "gravity_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gravity_space_override", PROPERTY_HINT_ENUM, "Disabled,Combine,Combine-Replace,Replace,Replace-Combine", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_space_override_mode", "get_gravity_space_override_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gravity_point", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_gravity_is_point", "is_gravity_a_point"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_distance_scale", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp"), "set_gravity_point_distance_scale", "get_gravity_point_distance_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_point_unit_distance", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,exp,suffix:px"), "set_gravity_point_unit_distance", "get_gravity_point_unit_distance"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_point_center", PROPERTY_HINT_NONE, "suffix:px"), "set_gravity_point_center", "get_gravity_point_center"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity_direction"), "set_gravity_direction", "get_gravity_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, U"-4096,4096,0.001,or_less,or_greater,suffix:px/s\u00B2"), "set_gravity", "get_gravity"); @@ -652,6 +652,7 @@ Area2D::Area2D() : set_gravity_direction(Vector2(0, 1)); set_monitoring(true); set_monitorable(true); + set_hide_clip_children(true); } Area2D::~Area2D() { diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index aaf7ea28f8..8f4bbe3219 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -51,7 +51,7 @@ private: Vector2 gravity_vec; real_t gravity = 0.0; bool gravity_is_point = false; - real_t gravity_distance_scale = 0.0; + real_t gravity_point_unit_distance = 0.0; SpaceOverride linear_damp_space_override = SPACE_OVERRIDE_DISABLED; SpaceOverride angular_damp_space_override = SPACE_OVERRIDE_DISABLED; @@ -144,8 +144,8 @@ public: void set_gravity_is_point(bool p_enabled); bool is_gravity_a_point() const; - void set_gravity_point_distance_scale(real_t p_scale); - real_t get_gravity_point_distance_scale() const; + void set_gravity_point_unit_distance(real_t p_scale); + real_t get_gravity_point_unit_distance() const; void set_gravity_point_center(const Vector2 &p_center); const Vector2 &get_gravity_point_center() const; diff --git a/scene/2d/audio_listener_2d.cpp b/scene/2d/audio_listener_2d.cpp index 5b8833ce62..b4484694a5 100644 --- a/scene/2d/audio_listener_2d.cpp +++ b/scene/2d/audio_listener_2d.cpp @@ -110,3 +110,7 @@ void AudioListener2D::_bind_methods() { ClassDB::bind_method(D_METHOD("clear_current"), &AudioListener2D::clear_current); ClassDB::bind_method(D_METHOD("is_current"), &AudioListener2D::is_current); } + +AudioListener2D::AudioListener2D() { + set_hide_clip_children(true); +} diff --git a/scene/2d/audio_listener_2d.h b/scene/2d/audio_listener_2d.h index 12a44f26ae..abada06971 100644 --- a/scene/2d/audio_listener_2d.h +++ b/scene/2d/audio_listener_2d.h @@ -54,6 +54,8 @@ public: void make_current(); void clear_current(); bool is_current() const; + + AudioListener2D(); }; #endif // AUDIO_LISTENER_2D_H diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 8c23d33402..902fba38bf 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -486,6 +486,7 @@ void AudioStreamPlayer2D::_bind_methods() { AudioStreamPlayer2D::AudioStreamPlayer2D() { AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer2D::_bus_layout_changed)); cached_global_panning_strength = GLOBAL_GET("audio/general/2d_panning_strength"); + set_hide_clip_children(true); } AudioStreamPlayer2D::~AudioStreamPlayer2D() { diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index ab048f0cd7..60b344b002 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -101,6 +101,7 @@ void BackBufferCopy::_bind_methods() { BackBufferCopy::BackBufferCopy() { _update_copy_mode(); + set_hide_clip_children(true); } BackBufferCopy::~BackBufferCopy() { diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index c4647ae9ff..fe6bee0f1b 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -50,7 +50,7 @@ void Camera2D::_update_scroll() { return; } - if (current) { + if (is_current()) { ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id)); Transform2D xform = get_camera_transform(); @@ -241,10 +241,6 @@ void Camera2D::_notification(int p_what) { viewport = get_viewport(); } - if (is_current()) { - viewport->_camera_2d_set(this); - } - canvas = get_canvas(); RID vp = viewport->get_viewport_rid(); @@ -254,21 +250,21 @@ void Camera2D::_notification(int p_what) { add_to_group(group_name); add_to_group(canvas_group_name); + if (!Engine::get_singleton()->is_editor_hint() && enabled && !viewport->get_camera_2d()) { + make_current(); + } + _update_process_callback(); first = true; _update_scroll(); } break; case NOTIFICATION_EXIT_TREE: { - if (is_current()) { - if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { - viewport->set_canvas_transform(Transform2D()); - clear_current(); - current = true; - } - } remove_from_group(group_name); remove_from_group(canvas_group_name); + if (is_current()) { + clear_current(); + } viewport = nullptr; } break; @@ -397,19 +393,31 @@ void Camera2D::set_process_callback(Camera2DProcessCallback p_mode) { _update_process_callback(); } +void Camera2D::set_enabled(bool p_enabled) { + enabled = p_enabled; + + if (enabled && is_inside_tree() && !viewport->get_camera_2d()) { + make_current(); + } else if (!enabled && is_current()) { + clear_current(); + } +} + +bool Camera2D::is_enabled() const { + return enabled; +} + Camera2D::Camera2DProcessCallback Camera2D::get_process_callback() const { return process_callback; } void Camera2D::_make_current(Object *p_which) { if (p_which == this) { - current = true; if (is_inside_tree()) { get_viewport()->_camera_2d_set(this); queue_redraw(); } } else { - current = false; if (is_inside_tree()) { if (get_viewport()->get_camera_2d() == this) { get_viewport()->_camera_2d_set(nullptr); @@ -419,45 +427,34 @@ void Camera2D::_make_current(Object *p_which) { } } -void Camera2D::set_current(bool p_current) { - if (p_current) { - make_current(); - } else { - if (current) { - clear_current(); - } - } -} - void Camera2D::_update_process_internal_for_smoothing() { bool is_not_in_scene_or_editor = !(is_inside_tree() && Engine::get_singleton()->is_editor_hint()); bool is_any_smoothing_valid = position_smoothing_speed > 0 || rotation_smoothing_speed > 0; - bool enabled = is_any_smoothing_valid && is_not_in_scene_or_editor; - set_process_internal(enabled); -} - -bool Camera2D::is_current() const { - return current; + bool enable = is_any_smoothing_valid && is_not_in_scene_or_editor; + set_process_internal(enable); } void Camera2D::make_current() { - if (is_inside_tree()) { - get_tree()->call_group(group_name, "_make_current", this); - } else { - current = true; - } + ERR_FAIL_COND(!enabled || !is_inside_tree()); + get_tree()->call_group(group_name, "_make_current", this); _update_scroll(); } void Camera2D::clear_current() { - if (is_inside_tree()) { - get_tree()->call_group(group_name, "_make_current", (Object *)nullptr); - } else { - current = false; + ERR_FAIL_COND(!is_current()); + if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { + viewport->assign_next_enabled_camera_2d(group_name); } } +bool Camera2D::is_current() const { + if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) { + return viewport->get_camera_2d() == this; + } + return false; +} + void Camera2D::set_limit(Side p_side, int p_limit) { ERR_FAIL_INDEX((int)p_side, 4); limit[p_side] = p_limit; @@ -715,7 +712,10 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_process_callback", "mode"), &Camera2D::set_process_callback); ClassDB::bind_method(D_METHOD("get_process_callback"), &Camera2D::get_process_callback); - ClassDB::bind_method(D_METHOD("set_current", "current"), &Camera2D::set_current); + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Camera2D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &Camera2D::is_enabled); + + ClassDB::bind_method(D_METHOD("make_current"), &Camera2D::make_current); ClassDB::bind_method(D_METHOD("is_current"), &Camera2D::is_current); ClassDB::bind_method(D_METHOD("_make_current"), &Camera2D::_make_current); @@ -779,7 +779,7 @@ void Camera2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_offset", "get_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_rotation"), "set_ignore_rotation", "is_ignoring_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "current"), "set_current", "is_current"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom", PROPERTY_HINT_LINK), "set_zoom", "get_zoom"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_viewport", PROPERTY_HINT_RESOURCE_TYPE, "Viewport", PROPERTY_USAGE_NONE), "set_custom_viewport", "get_custom_viewport"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback"); @@ -832,4 +832,5 @@ Camera2D::Camera2D() { drag_margin[SIDE_BOTTOM] = 0.2; set_notify_transform(true); + set_hide_clip_children(true); } diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 304b4ceaa6..7a77266db8 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -64,7 +64,7 @@ protected: Vector2 zoom_scale = Vector2(1, 1); AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER; bool ignore_rotation = true; - bool current = false; + bool enabled = true; real_t position_smoothing_speed = 5.0; bool follow_smoothing_enabled = false; @@ -88,7 +88,6 @@ protected: void _update_scroll(); void _make_current(Object *p_which); - void set_current(bool p_current); void _set_old_smoothing(real_t p_enable); @@ -155,6 +154,9 @@ public: void set_process_callback(Camera2DProcessCallback p_mode); Camera2DProcessCallback get_process_callback() const; + void set_enabled(bool p_enabled); + bool is_enabled() const; + void make_current(); void clear_current(); bool is_current() const; diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index caea753d99..ba3b0cec5c 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -651,6 +651,7 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) { area = p_area; pickable = true; set_notify_transform(true); + set_hide_clip_children(true); total_subshapes = 0; only_update_transform_changes = false; diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 0e18f77b8a..32dea80650 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -131,15 +131,7 @@ void CollisionPolygon2D::_notification(int p_what) { break; } - int polygon_count = polygon.size(); - for (int i = 0; i < polygon_count; i++) { - Vector2 p = polygon[i]; - Vector2 n = polygon[(i + 1) % polygon_count]; - // draw line with width <= 1, so it does not scale with zoom and break pixel exact editing - draw_line(p, n, Color(0.9, 0.2, 0.0, 0.8), 1); - } - - if (polygon_count > 2) { + if (polygon.size() > 2) { #define DEBUG_DECOMPOSE #if defined(TOOLS_ENABLED) && defined(DEBUG_DECOMPOSE) Vector<Vector<Vector2>> decomp = _decompose_in_convex(); @@ -152,6 +144,11 @@ void CollisionPolygon2D::_notification(int p_what) { #else draw_colored_polygon(polygon, get_tree()->get_debug_collisions_color()); #endif + + const Color stroke_color = Color(0.9, 0.2, 0.0); + draw_polyline(polygon, stroke_color); + // Draw the last segment. + draw_line(polygon[polygon.size() - 1], polygon[0], stroke_color); } if (one_way_collision) { @@ -323,4 +320,5 @@ void CollisionPolygon2D::_bind_methods() { CollisionPolygon2D::CollisionPolygon2D() { set_notify_local_transform(true); + set_hide_clip_children(true); } diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 6ff789cad2..5951405bbe 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -288,5 +288,6 @@ void CollisionShape2D::_bind_methods() { CollisionShape2D::CollisionShape2D() { set_notify_local_transform(true); + set_hide_clip_children(true); debug_color = _get_default_debug_color(); } diff --git a/scene/2d/joint_2d.cpp b/scene/2d/joint_2d.cpp index 47d0ac6e35..ce427d47aa 100644 --- a/scene/2d/joint_2d.cpp +++ b/scene/2d/joint_2d.cpp @@ -243,6 +243,7 @@ void Joint2D::_bind_methods() { Joint2D::Joint2D() { joint = PhysicsServer2D::get_singleton()->joint_create(); + set_hide_clip_children(true); } Joint2D::~Joint2D() { diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index fb53400fd6..15b638ed92 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -443,6 +443,7 @@ void PointLight2D::_bind_methods() { PointLight2D::PointLight2D() { RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_POINT); + set_hide_clip_children(true); } ////////// @@ -467,4 +468,5 @@ void DirectionalLight2D::_bind_methods() { DirectionalLight2D::DirectionalLight2D() { RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_DIRECTIONAL); set_max_distance(max_distance); // Update RenderingServer. + set_hide_clip_children(true); } diff --git a/scene/2d/marker_2d.cpp b/scene/2d/marker_2d.cpp index 512875833c..9595fcfffe 100644 --- a/scene/2d/marker_2d.cpp +++ b/scene/2d/marker_2d.cpp @@ -117,4 +117,5 @@ void Marker2D::_bind_methods() { } Marker2D::Marker2D() { + set_hide_clip_children(true); } diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp index e73b6e7e23..85f6840fde 100644 --- a/scene/2d/navigation_agent_2d.cpp +++ b/scene/2d/navigation_agent_2d.cpp @@ -108,6 +108,26 @@ void NavigationAgent2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_time_horizon", "get_time_horizon"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed"); +#ifdef DEBUG_ENABLED + ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent2D::set_debug_enabled); + ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent2D::get_debug_enabled); + ClassDB::bind_method(D_METHOD("set_debug_use_custom", "enabled"), &NavigationAgent2D::set_debug_use_custom); + ClassDB::bind_method(D_METHOD("get_debug_use_custom"), &NavigationAgent2D::get_debug_use_custom); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_color", "color"), &NavigationAgent2D::set_debug_path_custom_color); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_color"), &NavigationAgent2D::get_debug_path_custom_color); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_point_size", "point_size"), &NavigationAgent2D::set_debug_path_custom_point_size); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_point_size"), &NavigationAgent2D::get_debug_path_custom_point_size); + ClassDB::bind_method(D_METHOD("set_debug_path_custom_line_width", "line_width"), &NavigationAgent2D::set_debug_path_custom_line_width); + ClassDB::bind_method(D_METHOD("get_debug_path_custom_line_width"), &NavigationAgent2D::get_debug_path_custom_line_width); + + ADD_GROUP("Debug", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_enabled"), "set_debug_enabled", "get_debug_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_line_width", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_line_width", "get_debug_path_custom_line_width"); +#endif // DEBUG_ENABLED + ADD_SIGNAL(MethodInfo("path_changed")); ADD_SIGNAL(MethodInfo("target_reached")); ADD_SIGNAL(MethodInfo("waypoint_reached", PropertyInfo(Variant::DICTIONARY, "details"))); @@ -120,9 +140,15 @@ void NavigationAgent2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_POST_ENTER_TREE: { // need to use POST_ENTER_TREE cause with normal ENTER_TREE not all required Nodes are ready. - // cannot use READY as ready does not get called if Node is readded to SceneTree + // cannot use READY as ready does not get called if Node is re-added to SceneTree set_agent_parent(get_parent()); set_physics_process_internal(true); + +#ifdef DEBUG_ENABLED + if (NavigationServer2D::get_singleton()->get_debug_enabled()) { + debug_path_dirty = true; + } +#endif // DEBUG_ENABLED } break; case NOTIFICATION_PARENTED: { @@ -142,6 +168,17 @@ void NavigationAgent2D::_notification(int p_what) { set_physics_process_internal(false); } break; + case NOTIFICATION_EXIT_TREE: { + set_agent_parent(nullptr); + set_physics_process_internal(false); + +#ifdef DEBUG_ENABLED + if (debug_path_instance.is_valid()) { + RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, false); + } +#endif // DEBUG_ENABLED + } break; + case NOTIFICATION_PAUSED: { if (agent_parent && !agent_parent->can_process()) { map_before_pause = NavigationServer2D::get_singleton()->agent_get_map(get_rid()); @@ -162,11 +199,6 @@ void NavigationAgent2D::_notification(int p_what) { } } break; - case NOTIFICATION_EXIT_TREE: { - agent_parent = nullptr; - set_physics_process_internal(false); - } break; - case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (agent_parent && target_position_submitted) { if (avoidance_enabled) { @@ -176,17 +208,22 @@ void NavigationAgent2D::_notification(int p_what) { } _check_distance_to_target(); } +#ifdef DEBUG_ENABLED + if (debug_path_dirty) { + _update_debug_path(); + } +#endif // DEBUG_ENABLED } break; } } NavigationAgent2D::NavigationAgent2D() { agent = NavigationServer2D::get_singleton()->agent_create(); - set_neighbor_distance(neighbor_distance); - set_max_neighbors(max_neighbors); - set_time_horizon(time_horizon); - set_radius(radius); - set_max_speed(max_speed); + NavigationServer2D::get_singleton()->agent_set_neighbor_distance(agent, neighbor_distance); + NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, max_neighbors); + NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, time_horizon); + NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); + NavigationServer2D::get_singleton()->agent_set_max_speed(agent, max_speed); // Preallocate query and result objects to improve performance. navigation_query = Ref<NavigationPathQueryParameters2D>(); @@ -194,16 +231,34 @@ NavigationAgent2D::NavigationAgent2D() { navigation_result = Ref<NavigationPathQueryResult2D>(); navigation_result.instantiate(); + +#ifdef DEBUG_ENABLED + NavigationServer2D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed)); +#endif // DEBUG_ENABLED } NavigationAgent2D::~NavigationAgent2D() { ERR_FAIL_NULL(NavigationServer2D::get_singleton()); NavigationServer2D::get_singleton()->free(agent); agent = RID(); // Pointless + +#ifdef DEBUG_ENABLED + NavigationServer2D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed)); + + ERR_FAIL_NULL(RenderingServer::get_singleton()); + if (debug_path_instance.is_valid()) { + RenderingServer::get_singleton()->free(debug_path_instance); + } +#endif // DEBUG_ENABLED } void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) { + if (avoidance_enabled == p_enabled) { + return; + } + avoidance_enabled = p_enabled; + if (avoidance_enabled) { NavigationServer2D::get_singleton()->agent_set_callback(agent, callable_mp(this, &NavigationAgent2D::_avoidance_done)); } else { @@ -216,6 +271,10 @@ bool NavigationAgent2D::get_avoidance_enabled() const { } void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) { + if (agent_parent == p_agent_parent) { + return; + } + // remove agent from any avoidance map before changing parent or there will be leftovers on the RVO map NavigationServer2D::get_singleton()->agent_set_callback(agent, Callable()); @@ -229,7 +288,9 @@ void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) { } // create new avoidance callback if enabled - set_avoidance_enabled(avoidance_enabled); + if (avoidance_enabled) { + NavigationServer2D::get_singleton()->agent_set_callback(agent, callable_mp(this, &NavigationAgent2D::_avoidance_done)); + } } else { agent_parent = nullptr; NavigationServer2D::get_singleton()->agent_set_map(get_rid(), RID()); @@ -237,11 +298,13 @@ void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) { } void NavigationAgent2D::set_navigation_layers(uint32_t p_navigation_layers) { - bool navigation_layers_changed = navigation_layers != p_navigation_layers; - navigation_layers = p_navigation_layers; - if (navigation_layers_changed) { - _request_repath(); + if (navigation_layers == p_navigation_layers) { + return; } + + navigation_layers = p_navigation_layers; + + _request_repath(); } uint32_t NavigationAgent2D::get_navigation_layers() const { @@ -275,7 +338,12 @@ void NavigationAgent2D::set_path_metadata_flags(BitField<NavigationPathQueryPara } void NavigationAgent2D::set_navigation_map(RID p_navigation_map) { + if (map_override == p_navigation_map) { + return; + } + map_override = p_navigation_map; + NavigationServer2D::get_singleton()->agent_set_map(agent, map_override); _request_repath(); } @@ -289,41 +357,78 @@ RID NavigationAgent2D::get_navigation_map() const { return RID(); } -void NavigationAgent2D::set_path_desired_distance(real_t p_dd) { - path_desired_distance = p_dd; +void NavigationAgent2D::set_path_desired_distance(real_t p_path_desired_distance) { + if (Math::is_equal_approx(path_desired_distance, p_path_desired_distance)) { + return; + } + + path_desired_distance = p_path_desired_distance; } -void NavigationAgent2D::set_target_desired_distance(real_t p_dd) { - target_desired_distance = p_dd; +void NavigationAgent2D::set_target_desired_distance(real_t p_target_desired_distance) { + if (Math::is_equal_approx(target_desired_distance, p_target_desired_distance)) { + return; + } + + target_desired_distance = p_target_desired_distance; } void NavigationAgent2D::set_radius(real_t p_radius) { + if (Math::is_equal_approx(radius, p_radius)) { + return; + } + radius = p_radius; + NavigationServer2D::get_singleton()->agent_set_radius(agent, radius); } void NavigationAgent2D::set_neighbor_distance(real_t p_distance) { + if (Math::is_equal_approx(neighbor_distance, p_distance)) { + return; + } + neighbor_distance = p_distance; + NavigationServer2D::get_singleton()->agent_set_neighbor_distance(agent, neighbor_distance); } void NavigationAgent2D::set_max_neighbors(int p_count) { + if (max_neighbors == p_count) { + return; + } + max_neighbors = p_count; + NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, max_neighbors); } void NavigationAgent2D::set_time_horizon(real_t p_time) { + if (Math::is_equal_approx(time_horizon, p_time)) { + return; + } + time_horizon = p_time; + NavigationServer2D::get_singleton()->agent_set_time_horizon(agent, time_horizon); } void NavigationAgent2D::set_max_speed(real_t p_max_speed) { + if (Math::is_equal_approx(max_speed, p_max_speed)) { + return; + } + max_speed = p_max_speed; + NavigationServer2D::get_singleton()->agent_set_max_speed(agent, max_speed); } -void NavigationAgent2D::set_path_max_distance(real_t p_pmd) { - path_max_distance = p_pmd; +void NavigationAgent2D::set_path_max_distance(real_t p_path_max_distance) { + if (Math::is_equal_approx(path_max_distance, p_path_max_distance)) { + return; + } + + path_max_distance = p_path_max_distance; } real_t NavigationAgent2D::get_path_max_distance() { @@ -331,8 +436,13 @@ real_t NavigationAgent2D::get_path_max_distance() { } void NavigationAgent2D::set_target_position(Vector2 p_position) { + if (target_position.is_equal_approx(p_position)) { + return; + } + target_position = p_position; target_position_submitted = true; + _request_repath(); } @@ -381,10 +491,15 @@ Vector2 NavigationAgent2D::get_final_position() { } void NavigationAgent2D::set_velocity(Vector2 p_velocity) { + if (target_velocity.is_equal_approx(p_velocity)) { + return; + } + target_velocity = p_velocity; + velocity_submitted = true; + NavigationServer2D::get_singleton()->agent_set_target_velocity(agent, target_velocity); NavigationServer2D::get_singleton()->agent_set_velocity(agent, prev_safe_velocity); - velocity_submitted = true; } void NavigationAgent2D::_avoidance_done(Vector3 p_new_velocity) { @@ -463,6 +578,9 @@ void NavigationAgent2D::update_navigation() { } NavigationServer2D::get_singleton()->query_path(navigation_query, navigation_result); +#ifdef DEBUG_ENABLED + debug_path_dirty = true; +#endif // DEBUG_ENABLED navigation_finished = false; navigation_path_index = 0; emit_signal(SNAME("path_changed")); @@ -549,3 +667,131 @@ void NavigationAgent2D::_check_distance_to_target() { } } } + +////////DEBUG//////////////////////////////////////////////////////////// + +#ifdef DEBUG_ENABLED +void NavigationAgent2D::set_debug_enabled(bool p_enabled) { + if (debug_enabled == p_enabled) { + return; + } + + debug_enabled = p_enabled; + debug_path_dirty = true; +} + +bool NavigationAgent2D::get_debug_enabled() const { + return debug_enabled; +} + +void NavigationAgent2D::set_debug_use_custom(bool p_enabled) { + if (debug_use_custom == p_enabled) { + return; + } + + debug_use_custom = p_enabled; + debug_path_dirty = true; +} + +bool NavigationAgent2D::get_debug_use_custom() const { + return debug_use_custom; +} + +void NavigationAgent2D::set_debug_path_custom_color(Color p_color) { + if (debug_path_custom_color == p_color) { + return; + } + + debug_path_custom_color = p_color; + debug_path_dirty = true; +} + +Color NavigationAgent2D::get_debug_path_custom_color() const { + return debug_path_custom_color; +} + +void NavigationAgent2D::set_debug_path_custom_point_size(float p_point_size) { + if (Math::is_equal_approx(debug_path_custom_point_size, p_point_size)) { + return; + } + + debug_path_custom_point_size = MAX(0.1, p_point_size); + debug_path_dirty = true; +} + +float NavigationAgent2D::get_debug_path_custom_point_size() const { + return debug_path_custom_point_size; +} + +void NavigationAgent2D::set_debug_path_custom_line_width(float p_line_width) { + if (Math::is_equal_approx(debug_path_custom_line_width, p_line_width)) { + return; + } + + debug_path_custom_line_width = p_line_width; + debug_path_dirty = true; +} + +float NavigationAgent2D::get_debug_path_custom_line_width() const { + return debug_path_custom_line_width; +} + +void NavigationAgent2D::_navigation_debug_changed() { + debug_path_dirty = true; +} + +void NavigationAgent2D::_update_debug_path() { + if (!debug_path_dirty) { + return; + } + debug_path_dirty = false; + + if (!debug_path_instance.is_valid()) { + debug_path_instance = RenderingServer::get_singleton()->canvas_item_create(); + } + + RenderingServer::get_singleton()->canvas_item_clear(debug_path_instance); + + if (!(debug_enabled && NavigationServer2D::get_singleton()->get_debug_navigation_enable_agent_paths())) { + return; + } + + if (!(agent_parent && agent_parent->is_inside_tree())) { + return; + } + + RenderingServer::get_singleton()->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas()); + RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree()); + + const Vector<Vector2> &navigation_path = navigation_result->get_path(); + + if (navigation_path.size() <= 1) { + return; + } + + Color debug_path_color = NavigationServer2D::get_singleton()->get_debug_navigation_agent_path_color(); + if (debug_use_custom) { + debug_path_color = debug_path_custom_color; + } + + Vector<Color> debug_path_colors; + debug_path_colors.resize(navigation_path.size()); + debug_path_colors.fill(debug_path_color); + + RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false); + + float point_size = NavigationServer2D::get_singleton()->get_debug_navigation_agent_path_point_size(); + float half_point_size = point_size * 0.5; + + if (debug_use_custom) { + point_size = debug_path_custom_point_size; + half_point_size = debug_path_custom_point_size * 0.5; + } + + for (int i = 0; i < navigation_path.size(); i++) { + const Vector2 &vert = navigation_path[i]; + Rect2 path_point_rect = Rect2(vert.x - half_point_size, vert.y - half_point_size, point_size, point_size); + RenderingServer::get_singleton()->canvas_item_add_rect(debug_path_instance, path_point_rect, debug_path_color); + } +} +#endif // DEBUG_ENABLED diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h index 9787bb1bdb..5278c81f66 100644 --- a/scene/2d/navigation_agent_2d.h +++ b/scene/2d/navigation_agent_2d.h @@ -57,7 +57,6 @@ class NavigationAgent2D : public Node { int max_neighbors = 10; real_t time_horizon = 1.0; real_t max_speed = 100.0; - real_t path_max_distance = 100.0; Vector2 target_position; @@ -74,6 +73,20 @@ class NavigationAgent2D : public Node { // No initialized on purpose uint32_t update_frame_id = 0; +#ifdef DEBUG_ENABLED + bool debug_enabled = false; + bool debug_path_dirty = true; + RID debug_path_instance; + float debug_path_custom_point_size = 4.0; + float debug_path_custom_line_width = 1.0; + bool debug_use_custom = false; + Color debug_path_custom_color = Color(1.0, 1.0, 1.0, 1.0); + +private: + void _navigation_debug_changed(); + void _update_debug_path(); +#endif // DEBUG_ENABLED + protected: static void _bind_methods(); void _notification(int p_what); @@ -169,6 +182,23 @@ public: PackedStringArray get_configuration_warnings() const override; +#ifdef DEBUG_ENABLED + void set_debug_enabled(bool p_enabled); + bool get_debug_enabled() const; + + void set_debug_use_custom(bool p_enabled); + bool get_debug_use_custom() const; + + void set_debug_path_custom_color(Color p_color); + Color get_debug_path_custom_color() const; + + void set_debug_path_custom_point_size(float p_point_size); + float get_debug_path_custom_point_size() const; + + void set_debug_path_custom_line_width(float p_line_width); + float get_debug_path_custom_line_width() const; +#endif // DEBUG_ENABLED + private: void update_navigation(); void _request_repath(); diff --git a/scene/2d/navigation_link_2d.cpp b/scene/2d/navigation_link_2d.cpp index 65bf178cc5..26dca40176 100644 --- a/scene/2d/navigation_link_2d.cpp +++ b/scene/2d/navigation_link_2d.cpp @@ -308,6 +308,7 @@ NavigationLink2D::NavigationLink2D() { NavigationServer2D::get_singleton()->link_set_owner_id(link, get_instance_id()); set_notify_transform(true); + set_hide_clip_children(true); } NavigationLink2D::~NavigationLink2D() { diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index 4bd170301a..d7ef77e25b 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -185,6 +185,10 @@ real_t NavigationObstacle2D::estimate_agent_radius() const { } void NavigationObstacle2D::set_agent_parent(Node *p_agent_parent) { + if (parent_node2d == p_agent_parent) { + return; + } + if (Object::cast_to<Node2D>(p_agent_parent) != nullptr) { parent_node2d = Object::cast_to<Node2D>(p_agent_parent); if (map_override.is_valid()) { @@ -200,7 +204,12 @@ void NavigationObstacle2D::set_agent_parent(Node *p_agent_parent) { } void NavigationObstacle2D::set_navigation_map(RID p_navigation_map) { + if (map_override == p_navigation_map) { + return; + } + map_override = p_navigation_map; + NavigationServer2D::get_singleton()->agent_set_map(agent, map_override); } @@ -214,13 +223,23 @@ RID NavigationObstacle2D::get_navigation_map() const { } void NavigationObstacle2D::set_estimate_radius(bool p_estimate_radius) { + if (estimate_radius == p_estimate_radius) { + return; + } + 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."); + if (Math::is_equal_approx(radius, p_radius)) { + return; + } + radius = p_radius; + reevaluate_agent_radius(); } diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp index fe6af8dad2..3484a9de65 100644 --- a/scene/2d/navigation_region_2d.cpp +++ b/scene/2d/navigation_region_2d.cpp @@ -330,6 +330,7 @@ bool NavigationRegion2D::_get(const StringName &p_name, Variant &r_ret) const { NavigationRegion2D::NavigationRegion2D() { set_notify_transform(true); + set_hide_clip_children(true); region = NavigationServer2D::get_singleton()->region_create(); NavigationServer2D::get_singleton()->region_set_owner_id(region, get_instance_id()); diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 39f88a0b5e..988ea87054 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -370,4 +370,5 @@ void RayCast2D::_bind_methods() { } RayCast2D::RayCast2D() { + set_hide_clip_children(true); } diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index e9ce9560d3..c6730f7ab2 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -219,4 +219,5 @@ void RemoteTransform2D::_bind_methods() { RemoteTransform2D::RemoteTransform2D() { set_notify_transform(true); + set_hide_clip_children(true); } diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp index 24821858cf..bafb83361a 100644 --- a/scene/2d/shape_cast_2d.cpp +++ b/scene/2d/shape_cast_2d.cpp @@ -472,3 +472,7 @@ void ShapeCast2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); } + +ShapeCast2D::ShapeCast2D() { + set_hide_clip_children(true); +} diff --git a/scene/2d/shape_cast_2d.h b/scene/2d/shape_cast_2d.h index 182614a721..8a62b799f8 100644 --- a/scene/2d/shape_cast_2d.h +++ b/scene/2d/shape_cast_2d.h @@ -119,6 +119,8 @@ public: void clear_exceptions(); PackedStringArray get_configuration_warnings() const override; + + ShapeCast2D(); }; #endif // SHAPE_CAST_2D_H diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 83cfffc333..96711bbe72 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -519,6 +519,7 @@ Bone2D::Bone2D() { bone_angle = 0; autocalculate_length_and_angle = true; set_notify_local_transform(true); + set_hide_clip_children(true); //this is a clever hack so the bone knows no rest has been set yet, allowing to show an error. for (int i = 0; i < 3; i++) { rest[i] = Vector2(0, 0); @@ -801,6 +802,7 @@ void Skeleton2D::_bind_methods() { Skeleton2D::Skeleton2D() { skeleton = RS::get_singleton()->skeleton_create(); set_notify_transform(true); + set_hide_clip_children(true); } Skeleton2D::~Skeleton2D() { diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index a1304ab991..95bf67d38d 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -3969,6 +3969,17 @@ PackedStringArray TileMap::get_configuration_warnings() const { } } + // Check if Y-sort is enabled on a layer but not on the node. + if (!is_y_sort_enabled()) { + for (const TileMapLayer &layer : layers) { + if (layer.y_sort_enabled) { + warnings.push_back(RTR("A TileMap layer is set as Y-sorted, but Y-sort is not enabled on the TileMap node itself.")); + break; + } + } + } + + // Check if we are in isometric mode without Y-sort enabled. if (tile_set.is_valid() && tile_set->get_tile_shape() == TileSet::TILE_SHAPE_ISOMETRIC) { bool warn = !is_y_sort_enabled(); if (!warn) { diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp index 237eb3d987..1177cdb811 100644 --- a/scene/2d/visible_on_screen_notifier_2d.cpp +++ b/scene/2d/visible_on_screen_notifier_2d.cpp @@ -110,6 +110,7 @@ void VisibleOnScreenNotifier2D::_bind_methods() { VisibleOnScreenNotifier2D::VisibleOnScreenNotifier2D() { rect = Rect2(-10, -10, 20, 20); + set_hide_clip_children(true); } ////////////////////////////////////// |