Skip to content
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

Setting transform for a Node2D outside the tree doesn't invalidate the global_transform #79214

Closed
nbaum opened this issue Jul 8, 2023 · 1 comment
Milestone

Comments

@nbaum
Copy link

nbaum commented Jul 8, 2023

Godot version

v4.1.stable.official

System information

Godot v4.1.stable - Arch Linux #1 SMP PREEMPT_DYNAMIC Wed, 21 Jun 2023 20:46:20 +0000 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 (nvidia; 535.54.03) - AMD Ryzen 9 5950X 16-Core Processor (32 Threads)

Issue description

Setting transform for a Node2D outside the tree doesn't invalidate global_transform, so after setting transform, reading global_transform doesn't reflect the change.

Because set_global_transform internally sets transform and does not invalidate the global one, this also means that if you set global_transform and then immediately read it back, you don't get the transform you just set. This was why I noticed the bug.

I infer from #67710 that reading the global_transform of a Node2D which is outside the tree is expected to work and should return the transform relative to the root of the disconnected tree branch.

It seems that prior to 0a9f72d, a newly created CanvasItem's global_transform was marked as invalid, so the first time it is read, it is updated from the current transform. After that commit, the global_transform appears to be marked as valid from birth.

Manually invoking _invalidate_global_transform on the node causes global_transform to update as expected, the next time it is read. Perhaps the solution is doing that automatically in set_transform, something which currently only happens if the transform is in the tree?

A Node3D has the same behaviour, but it is still considered an error to access the global_transform outside the tree, and an error is reported when you try to do so.

Steps to reproduce

Make any node and attach a script to it:

extends Node

func _ready() -> void:
  var node := Node2D.new()
  node.transform.origin.x = 1
  assert(node.global_transform.origin.x == 1, "First assignment got lost")
  node.transform.origin.x = 2
  assert(node.global_transform.origin.x == 2, "Second assignment got lost")

In 4.1, the first assertion will fail. In versions before 0a9f72d, the first assertion will pass, but the second assertion will fail.

Minimal reproduction project

node2d-transform-bug.zip

@lawnjelly lawnjelly added this to the 4.x milestone Jul 12, 2023
@kleonc
Copy link
Member

kleonc commented Apr 27, 2024

Can reproduce in:

Can't reproduce in:

  • v4.1.2.stable.official [399c9dc]
  • v4.1.3.stable.official [f06b6836a]
  • v4.1.4.stable.official [fe0e8e5]
  • v4.2.stable.official [46dc277]
  • v4.2.1.stable.official [b09f793]
  • v4.2.2.stable.official [15073af
  • v4.3.dev5.official [89f70e9]

Closing as fixed, likely by #80105.

@kleonc kleonc closed this as completed Apr 27, 2024
@kleonc kleonc modified the milestones: 4.x, 4.2 Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants