diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 11fe595daf0..f084f5bdbdf 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -653,6 +653,9 @@ The [CanvasItem] has exited the canvas. + + The [CanvasItem]'s active [World2D] changed. + The [CanvasItem] will inherit the filter from its parent. diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index ba3b0cec5c1..ab42c52913b 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -118,6 +118,15 @@ void CollisionObject2D::_notification(int p_what) { } } break; + case NOTIFICATION_WORLD_2D_CHANGED: { + RID space = get_world_2d()->get_space(); + if (area) { + PhysicsServer2D::get_singleton()->area_set_space(rid, space); + } else { + PhysicsServer2D::get_singleton()->body_set_space(rid, space); + } + } break; + case NOTIFICATION_DISABLED: { _apply_disabled(); } break; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index b36353158b7..ee10f7988eb 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -336,6 +336,10 @@ void CanvasItem::_notification(int p_what) { case NOTIFICATION_VISIBILITY_CHANGED: { emit_signal(SceneStringNames::get_singleton()->visibility_changed); } break; + case NOTIFICATION_WORLD_2D_CHANGED: { + _exit_canvas(); + _enter_canvas(); + } } } @@ -1108,6 +1112,7 @@ void CanvasItem::_bind_methods() { BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); BIND_CONSTANT(NOTIFICATION_ENTER_CANVAS); BIND_CONSTANT(NOTIFICATION_EXIT_CANVAS); + BIND_CONSTANT(NOTIFICATION_WORLD_2D_CHANGED); BIND_ENUM_CONSTANT(TEXTURE_FILTER_PARENT_NODE); BIND_ENUM_CONSTANT(TEXTURE_FILTER_NEAREST); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8cd57536bf0..b226314ea96 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1047,7 +1047,11 @@ void Viewport::set_world_2d(const Ref &p_world_2d) { } if (p_world_2d.is_valid()) { + bool do_propagate = world_2d.is_valid() && is_inside_tree(); world_2d = p_world_2d; + if (do_propagate) { + _propagate_world_2d_changed(this); + } } else { WARN_PRINT("Invalid world_2d"); world_2d = Ref(memnew(World2D)); @@ -3807,6 +3811,25 @@ float Viewport::get_texture_mipmap_bias() const { #endif // _3D_DISABLED +void Viewport::_propagate_world_2d_changed(Node *p_node) { + if (p_node != this) { + if (Object::cast_to(p_node)) { + p_node->notification(CanvasItem::NOTIFICATION_WORLD_2D_CHANGED); + } else { + Viewport *v = Object::cast_to(p_node); + if (v) { + if (v->world_2d.is_valid()) { + return; + } + } + } + } + + for (int i = 0; i < p_node->get_child_count(); ++i) { + _propagate_world_2d_changed(p_node->get_child(i)); + } +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d); ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 5213c0db018..c0988de0fa5 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -729,6 +729,8 @@ public: bool is_using_xr(); #endif // _3D_DISABLED + void _propagate_world_2d_changed(Node *p_node); + void _validate_property(PropertyInfo &p_property) const; Viewport(); ~Viewport();