Right now, if you want to change parent of a node, you need to do:
node.get_parent().remove_child(node)
new_parent.add_child(node)
This already causes problems, as I see people confused on why they can't just add_child() to another node (the fact that they don't read/can't understand the error they are show is another thing). It's even worse if you want to reparent a Node2D. When doing above code, the result usually is "why my node has disappeared??!!!" (this is people not understanding local transform, but whatever).
Anyways, with 2D and 3D nodes you need:
var old_position = node.global_position
node.get_parent().remove_child(node)
new_parent.add_child(node)
node.global_position = old_position
That's... too much writing for a simple thing. So I'm proposing this:
Node.reparent(new_parent, keep_global_transform = true)
What it does is changing the parent of a node to new one. In some cases, it allows to avoid temporary variables if you want to e.g. move to granpdarent. The method would be overloaded for CanvasItem and Spatial to automatically (and optionally) retain the global_transform, so the node stays in place, like it is in editor actually.
This is somewhat related to #8788, but I'm proposing a more universal and concrete thing.
I've gotten used to it, but yeah I do agree, it would be more complete with it.
The transform part though has a bit of wrinkle. The tree handling stuff is in the Node class, which doesn't have canvas or spatial information. It would seem that the feature would get kind of awkward in the Node hierarchy.
Nodes extend into several types, so only Spatial and CanvasItem would be able to act on that parameter. It seems like it might need to have overloading or overriding involved. I wonder how it would be done and if there are any existing examples...
Or messy things like having conditional logic stuffed into the Node about which types should do something with that argument, and what.
There also might be a hot debate on keep_global_transform = true vs keep_global_transform = false. XD
I'm not actually aware of transforms, but a lot about enter/exit tree notifications. It would be awesome if I had that reparent method which does not fires enter/exit tree notifications (maybe NOTIFICATION_PATH_CHANGED could be useful).
I'm not actually aware of transforms, but a lot about enter/exit tree notifications. It would be awesome if I had that
reparentmethod which does not fires enter/exit tree notifications (maybeNOTIFICATION_PATH_CHANGEDcould be useful).
Exactly, and when using VisibilityNotifier2D for example, it sends a screen_exited signal on remove_child and a screen_entered signal on add_child but only in next update which can get messy to handle.
I think this is a bad idea, as it makes a simple function confusing. If you reparent a node, you should be aware the position is going to change. So making this an argument in the Node class makes little sense to me.
That being said, I see no easy way to reapply a transform once the node is moved. So we should probably add a transform and global_transform properties to CanvasItem.
I would also like to keep node's global transform then adding node as child :
Node.add_child( child_node, keep_global_transform = true ).
Closing. There's a very similar proposal https://github.com/godotengine/godot-proposals/issues/153
Also there's a PR open that resolves both.