@@ -157,6 +157,7 @@ void Spatial::_notification(int p_what) {
157
157
} else {
158
158
data.C = nullptr ;
159
159
}
160
+ _update_visible_in_tree ();
160
161
161
162
if (data.toplevel && !Engine::get_singleton ()->is_editor_hint ()) {
162
163
if (data.parent ) {
@@ -216,6 +217,8 @@ void Spatial::_notification(int p_what) {
216
217
data.parent = nullptr ;
217
218
data.C = nullptr ;
218
219
data.toplevel_active = false ;
220
+
221
+ _update_visible_in_tree ();
219
222
_disable_client_physics_interpolation ();
220
223
} break ;
221
224
case NOTIFICATION_ENTER_WORLD: {
@@ -732,6 +735,36 @@ Ref<World> Spatial::get_world() const {
732
735
return data.viewport ->find_world ();
733
736
}
734
737
738
+ void Spatial::_update_visible_in_tree () {
739
+ Spatial *parent = get_parent_spatial ();
740
+
741
+ bool propagate_visible = parent ? parent->data .visible_in_tree : true ;
742
+
743
+ // Only propagate visible when entering tree if we are visible.
744
+ propagate_visible &= is_visible ();
745
+
746
+ _propagate_visible_in_tree (this , propagate_visible);
747
+ }
748
+
749
+ void Spatial::_propagate_visible_in_tree (Spatial *p_node, bool p_visible_in_tree) {
750
+ // If any node is invisible, the propagation changes to invisible below.
751
+ p_visible_in_tree &= p_node->is_visible ();
752
+
753
+ // No change.
754
+ if (p_node->data .visible_in_tree == p_visible_in_tree) {
755
+ return ;
756
+ }
757
+
758
+ p_node->data .visible_in_tree = p_visible_in_tree;
759
+
760
+ for (int32_t n = 0 ; n < p_node->get_child_count (); n++) {
761
+ Spatial *s = Object::cast_to<Spatial>(p_node->get_child (n));
762
+ if (s) {
763
+ _propagate_visible_in_tree (s, p_visible_in_tree);
764
+ }
765
+ }
766
+ }
767
+
735
768
void Spatial::_propagate_visibility_changed () {
736
769
notification (NOTIFICATION_VISIBILITY_CHANGED);
737
770
emit_signal (SceneStringNames::get_singleton ()->visibility_changed );
@@ -791,6 +824,10 @@ void Spatial::show() {
791
824
return ;
792
825
}
793
826
827
+ bool parent_visible = get_parent_spatial () ? get_parent_spatial ()->data .visible_in_tree : true ;
828
+ if (parent_visible) {
829
+ _propagate_visible_in_tree (this , true );
830
+ }
794
831
_propagate_visibility_changed ();
795
832
}
796
833
@@ -805,10 +842,14 @@ void Spatial::hide() {
805
842
return ;
806
843
}
807
844
845
+ bool parent_visible = get_parent_spatial () ? get_parent_spatial ()->data .visible_in_tree : true ;
846
+ if (parent_visible) {
847
+ _propagate_visible_in_tree (this , false );
848
+ }
808
849
_propagate_visibility_changed ();
809
850
}
810
851
811
- bool Spatial::is_visible_in_tree () const {
852
+ bool Spatial::_is_visible_in_tree_reference () const {
812
853
const Spatial *s = this ;
813
854
814
855
while (s) {
@@ -1121,6 +1162,7 @@ Spatial::Spatial() :
1121
1162
data.viewport = nullptr ;
1122
1163
data.inside_world = false ;
1123
1164
data.visible = true ;
1165
+ data.visible_in_tree = true ;
1124
1166
data.disable_scale = false ;
1125
1167
data.vi_visible = true ;
1126
1168
data.merging_allowed = true ;
0 commit comments