Browse Source

Merge pull request #75509 from KoBeWi/In_physics,_the_observer_effect_is_the_disturbance_of_an_observed_system_by_the_act_of_observation._A_common_example_is_checking_CanvasItem's_global_position,_which_causes_its_transform_to_be_re-calculated-

Fix invalid global position when read outside tree
Rémi Verschelde 2 years ago
parent
commit
3695dfb357
2 changed files with 8 additions and 0 deletions
  1. 7 0
      scene/main/canvas_item.cpp
  2. 1 0
      scene/main/canvas_item.h

+ 7 - 0
scene/main/canvas_item.cpp

@@ -142,6 +142,10 @@ void CanvasItem::_redraw_callback() {
 	pending_update = false; // don't change to false until finished drawing (avoid recursive update)
 }
 
+void CanvasItem::_invalidate_global_transform() {
+	global_invalid = true;
+}
+
 Transform2D CanvasItem::get_global_transform_with_canvas() const {
 	if (canvas_layer) {
 		return canvas_layer->get_final_transform() * get_global_transform();
@@ -290,6 +294,7 @@ void CanvasItem::_notification(int p_what) {
 				}
 			}
 
+			global_invalid = true;
 			_enter_canvas();
 
 			RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, is_visible_in_tree()); // The visibility of the parent may change.
@@ -403,6 +408,7 @@ void CanvasItem::set_as_top_level(bool p_top_level) {
 
 	if (!is_inside_tree()) {
 		top_level = p_top_level;
+		propagate_call(SNAME("_invalidate_global_transform"));
 		return;
 	}
 
@@ -950,6 +956,7 @@ void CanvasItem::_validate_property(PropertyInfo &p_property) const {
 
 void CanvasItem::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_top_level_raise_self"), &CanvasItem::_top_level_raise_self);
+	ClassDB::bind_method(D_METHOD("_invalidate_global_transform"), &CanvasItem::_invalidate_global_transform);
 
 #ifdef TOOLS_ENABLED
 	ClassDB::bind_method(D_METHOD("_edit_set_state", "state"), &CanvasItem::_edit_set_state);

+ 1 - 0
scene/main/canvas_item.h

@@ -129,6 +129,7 @@ private:
 	virtual void _top_level_changed_on_parent();
 
 	void _redraw_callback();
+	void _invalidate_global_transform();
 
 	void _enter_canvas();
 	void _exit_canvas();