-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
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
Fix global transform being wrong on entering tree #86841
Fix global transform being wrong on entering tree #86841
Conversation
21b9d3f
to
9e73b6e
Compare
What about nested nodes
Now conceptually do node_a.remove_child(node_b)
node_d.add_child(node_b)
I would consider this indeed a problem. |
I think that, in that case, it should work correctly, as the |
9e73b6e
to
94407bc
Compare
Updated the PR, moving things to |
Ah thanks. The problem might come from #80105 then, where |
It appears, that in #80105 I was mistaken by my assumption, that I could move to the invalidation call from ENTER_TREE to PARENTED. Now I understand the problems of this change. Before #80105, #80105 got cherry-picked to 4.1.2, should this fix also make it into the next 4.1 release? |
I don't know if it has any implication but I guess it should have no significant impact to move it back there (from what I read in the code). I'll update the PR to move the statement where it was before then. Edit: done. |
94407bc
to
0a726d6
Compare
I'm not sure if there's really a bug within the CanvasItem notifications. If I understand it right, the issue with the mentioned TileMap's code is that it assumes that To me it seems rather like incorrect logic/handling of notifications on the TileMap side. Like it should likely be ensuring it's inside the tree when handling case NOTIFICATION_ENTER_TREE: {
...
set_notify_transform(true);
update_physics_stuff();
...
}
case NOTIFICATION_EXIT_TREE: {
...
set_notify_transform(false);
...
}
case NOTIFICATION_TRANSFORM_CHANGED: {
...
update_physics_stuff();
...
} To clarify, it's very likely that before the changes making CanvasItem's global transform work outside the tree (PRs from #86841 (comment) + probably some earlier ones) the If there's indeed some bug with the CanvasItem notifications that I'm not currently getting then for sure we should add test case(s) for such specific situation, to avoid potential regressions in the future (#80105 added some tests). |
The PR description is a bit outdated, but after investigating, the problem is not present only there. The global transform is wrong even in NOTIFICATION_ENTER_TREE. This is an issue, as there are several places in the code that rely on Edit: I tried adding some
Well, the TileMap code seems a bit weird I agree, but I tested that thoroughly: the global transform is 100% wrong when entering the tree. I tested it while removing all physics stuff, just keeping what was strictly necessary, and the global transform was still wrong when entering the tree. This PR fixes it. |
Ah, indeed - even if the TileMap is needlessly updating physics on
I suspect #85705 could have the same cause? 🤔 |
The bug, that this PR solves is not restricted to TileMaps. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tested the following MRPs:
- get_local_mouse_position does not work under certain circumstances #85705
- Tilemap Collision not colliding with player in 4.2 #85680 (comment)
This PR (rebased on 107f296) fixes both of them.
Thanks! |
Removing 4.1 cherry-pick as it wasn't confirmed for that branch (in fact, one of the closed issues implies it works correctly in 4.1.3), so to avoid the unexpected, let's keep things as is. |
Cherry-picked for 4.2.2. |
So, this is a tricky problem to explain. Basically, in the TileMap code, I used to do something like this (it's simplified so you get the idea):
After a long investigation on the TileMap code, I realized that the gl_transform provided there was wrong. Basically, when entering the tree,
get_global_transform
will provide wrong data on the firstNOTIFICATION_TRANSFORM_CHANGED
received (this notification is received on entering the tree, afterENTER_TREE
).What this PR does, is making sure that, on entering the tree, the CanvasItem global transform is marked as invalid right away. I am not 100% sure his is the most efficient / correct way to solve the issue, but it works.
I added it toNOTIFICATION_PARENTED
as it is the first notification to be triggered (at the CanvasItem level) when adding a CanvasItem to the tree. Also, it calls_notify_transform
right after, so not marking the global_transform as invalied seemed weird to me. I kind of guessed that when re-parented, the node's global_transform should always we set as invalid anyway.Another solution might be to set the flag in the constructor. As I guess that the fact theNOTIFICATION_EXIT_TREE
notification sets the state as invalid would probably be enough (basically, the problem seems to be the global_transform not being marked as invalid by default). I decided to add it toNOTIFICATION_PARENTED
as it seemed to make more sense.Edit: after some investigation, it seems like this notification is not always triggered, so I updated the PR to update things in NOTIFICATION_ENTER_TREE instead.
As a side note, something like this worked normally in GDScript:
I suspect that there's something in the
add_child
chain of events that does trigger the invalidation of theglobal_transform
later on, but not sure where.