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

Global position losing axis value when assigning axis values separately #87896

Open
KaySteinhoff opened this issue Feb 3, 2024 · 6 comments · May be fixed by #87440
Open

Global position losing axis value when assigning axis values separately #87896

KaySteinhoff opened this issue Feb 3, 2024 · 6 comments · May be fixed by #87440

Comments

@KaySteinhoff
Copy link

KaySteinhoff commented Feb 3, 2024

Tested versions

-Reproducible in Godot 4.2.1

System information

Godot v4.2.1.stable - Fedora Linux 39 (Workstation Edition) - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4060 Ti (nvidia; 535.154.05) - AMD Ryzen 7 5800X3D 8-Core Processor (16 Threads)

Issue description

I tried to generate a grid of boxes. Assigning the z position immediately after assigning x caused the x value to default to 0, same is true for the inverted setup or assigning z -> y -> x. All values except x are 0.

Steps to reproduce

extends Node3D

@export var width: int = 10
@export var depth: int = 10

var box = preload("res://Scenes/Box.tscn")

func _ready():
	for z in depth:
		for x in width:
			var boxInst: Node = box.instantiate()
			boxInst.global_position.x = x-(width>>1)
			boxInst.global_position.z = z-(depth>>1)
			add_child(boxInst)

Minimal reproduction project (MRP)

MRP.zip

A workaround is to do something in between assigning the values. Example:

extends Node3D

@export var width: int = 10
@export var depth: int = 10

var box = preload("res://Scenes/Box.tscn")

func _ready():
	for z in depth:
		for x in width:
			var boxInst: Node = box.instantiate()
			boxInst.global_position.x = x-(width>>1)
			add_child(boxInst)
			boxInst.global_position.z = z-(depth>>1)
@Lippanon
Copy link

Lippanon commented Feb 3, 2024

I don't see this as a bug, so much as a misunderstanding new Godot users seem to run into. I'll quote dalexeev from this (#74631) older issue:
"To me this looks to be expected. Until you add a node to the tree, it cannot have a global position, rotation, etc., since we don't yet know which branch the node will be added to. Perhaps we need to clarify this point in the docs and/or add a warning."

You should only alter the global_transform (origin/basis) after the node is added to the tree (with add_child).
This code works as expected:

add_child(boxInst)
boxInst.global_position.x = x-(width>>1)
boxInst.global_position.z = z-(depth>>1)

As a side note, like the linked issue says, only the last set will work which is why your "workaround" coincidentally works in this case. To demonstrate, the following code will leave all boxes at 0,0:

boxInst.global_position.x = x-(width>>1)
boxInst.global_position.z = z-(depth>>1)
boxInst.global_position.z = 0
add_child(boxInst)

I don't know if this is mentioned in the docs or tutorials, but if it's not it probably should as I see this come up often. First add_child, then set the global_position.

Finally I will add something that I think is sort of a bug. If you try to use global_transform.origin instead of global_position you will get errors (like #30445) informing you're trying to access the global_transform outside the tree. But when you use global_position directly, there is no such error, which probably shouldn't be the case, as that error is useful for new users to understand it isn't something you should do.

@Mickeon
Copy link
Contributor

Mickeon commented Feb 3, 2024

This pops up many, many times in different forms. It would be nice to address them once and for all.

It seems these kinds of issues stem from #30445 and may be solved by #70443.

I don't know if this is mentioned in the docs or tutorials, but if it's not it probably should as I see this come up often.

I have made note of it myself in #87440

@Mickeon Mickeon linked a pull request Feb 3, 2024 that will close this issue
@lostminds
Copy link

But when you use global_position directly, there is no such error, which probably shouldn't be the case, as that error is useful for new users to understand it isn't something you should do.

While I agree both global_position and global_transform are only useful when used on nodes in the tree, as their use is to include and apply parent transformations. And perhaps a warning could be useful if you do this without a parent. However, even if it's not the intended use I would have expected having no parent node and trying to access these would be the same as having a parent with no transform, in other words the same as just setting/getting the local node transform/position. The fact that it's not (at least according to the report above) seems a little buggy to me.

@KaySteinhoff
Copy link
Author

Seeing as this apparently isn't a bug but rather a misunderstanding of the use of Nodes I'm closing this issue

@AThousandShips
Copy link
Member

Let's keep this open until the PR has merged to track the documentation issue 🙂

@AThousandShips AThousandShips reopened this Feb 3, 2024
@tetrapod00
Copy link
Contributor

In addition to being documented in the Node3D (and Node2D?) class reference, this seems like a good candidate to be documented somewhere in the manual as well, wherever global space/global coordinates are explained. I'm not sure which page is best for that, since currently the there are several "entry points" into the docs - you can optionally read some or all of the Getting Started section, and the Manual section also has a couple "entry points" for understanding 3D coordinate spaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants