-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calling get_global_rect() inside an item_rect_changed callback behaves inconsistently #92449
Comments
Here is a slightly modified script that will fail an assertion when the error occurs (the game will halt when the error occurs). extends ColorRect
var p: Vector2
func _ready() -> void:
var timer := Timer.new()
timer.wait_time = 1
timer.autostart = true
timer.connect(
'timeout',
func move():
var t := Time.get_ticks_msec() / 1000.0
prints('setting position to: ', Vector2(t, t))
p = Vector2(t, t)
position = Vector2(t, t)
)
add_child(timer)
func _on_item_rect_changed() -> void:
var r := get_global_rect()
print('in item_rect_changed callback, get_global_rect() returns: ', r)
assert(r.position == p) The source code for Rect2 Control::get_global_rect() const {
ERR_READ_THREAD_GUARD_V(Rect2());
Transform2D xform = get_global_transform();
return Rect2(xform.get_origin(), xform.get_scale() * get_size());
} Some further testing confirms that |
Discussed this with @kleonc on Discord. @kleonc was able to reproduce the issue on Windows with Godot 4.2.2.stable. Discord discussion: https://discord.com/channels/212250894228652034/762480230559383562/1245071245008044123 We realized that you must move your mouse in and out of the ColorRect in order for this bug to happen. I've updated the original instructions. (I originally discovered this bug when experimenting with |
Reproducible also in current
It can be trigerred differently though, the issue seems to be that the global transform can end up incorrectly not invalidated during E.g.: extends ColorRect
var p: Vector2
func _notification(what: int) -> void:
match what:
NOTIFICATION_RESIZED:
print_info("NOTIFICATION_RESIZED")
NOTIFICATION_TRANSFORM_CHANGED:
print_info("NOTIFICATION_TRANSFORM_CHANGED")
NOTIFICATION_LOCAL_TRANSFORM_CHANGED:
print_info("NOTIFICATION_LOCAL_TRANSFORM_CHANGED")
func _ready() -> void:
var timer := Timer.new()
timer.wait_time = 1
timer.autostart = true
timer.connect(
'timeout',
func move():
var t := Time.get_ticks_msec() / 1000.0
print('[%4d] setting position to: %s' % [Engine.get_process_frames(), Vector2(t, t)])
p = Vector2(t, t)
position = Vector2(t, t)
)
add_child(timer)
func _on_item_rect_changed() -> void:
print_info("item_rect_changed")
func print_info(label: String) -> void:
var r := get_global_rect()
print("[%4d] %-30s get_global_rect()=%s" % [Engine.get_process_frames(), label, r])
if r.position != p:
print("^".repeat(80)) Outputs:
|
Tested versions
System information
Godot v4.2.1.stable (b09f793) - Fedora Linux 39 (Workstation Edition) - X11 - GLES3 (Compatibility) - NVIDIA GeForce RTX 3060 (nvidia; 550.54.14) - AMD Ryzen 9 5950X 16-Core Processor (32 Threads)
Issue description
Calling
get_global_rect()
inside aitem_rect_changed
callback behaves inconsistently. Sometimes it gives the rectangle as it was before the change that triggered the callback, and sometimes it gives the rectangle as it was after the change that triggered the callback.Steps to reproduce
item_rect_changed
signal to the appropriate function in the script.(Also, consider using the script in my next post which throws an error when this bug occurs.)
On my computer, the script output the following:
Notice that sometimes multiple calls to get_global_rect() return the same value. This should not happen because the node is continuously being moved to a new location. For example:
and
I believe this script and these logs make the issue self-evident.
Minimal reproduction project (MRP)
N/A - Just attach that script to a node, connect one signal, run the project, and observe the output.
The text was updated successfully, but these errors were encountered: