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

Control node draws out of order if it was initially a child of type Node #63183

Closed
ace24713 opened this issue Jul 19, 2022 · 4 comments · Fixed by #63235
Closed

Control node draws out of order if it was initially a child of type Node #63183

ace24713 opened this issue Jul 19, 2022 · 4 comments · Fixed by #63235

Comments

@ace24713
Copy link

Godot version

v3.4.4.stable.mono.official [419e713]

System information

Windows 10

Issue description

Saw this on a project I was working on, where a control node would be created as the child of a node, then reparented into it's correct location. Occasionally nodes initialized this way would draw in the wrong order, despite being in the right order in the tree.

The issue is present both with and without batched rendering.

Here's a screenshot of my test scene alongside the debug Remote tree. The red object should draw on top.
image

Steps to reproduce

This isn't the only way to reproduce this, but this is the approach in my reproduction scene.

First create a control node as a child of a type Node that is above the destination in the tree.
Then reparent the control node such that it is now below at least two siblings that were below it before.
Note the rendering order is incorrect.

Minimal reproduction project

Here's my test scene RenderingOrderIssue.zip

@timothyqiu
Copy link
Member

I remember there was an error when trying to call add_child() or move_child() in _ready() saying the parent is busy setting up children. I'm not sure why the error is not there in the case...

Anyway, as a workaround, you can call_defered("add_child", that_node) or yield for one idle frame in _ready().

@ace24713
Copy link
Author

That does result in the correct drawing order in the test project, but not in my actual program where the code instantiating the control node wasn't in a _ready call at all. I couldn't tell you what the difference is, but I am certain the problem stopped happening when I changed the type of the initial parent (an autoload) from Node to Control.

@ace24713
Copy link
Author

ace24713 commented Jul 19, 2022

A little more info.

Here's a modified _ready call that also reproduces the issue, with a 1 frame delay:

func _ready():
	yield(get_tree(), "idle_frame")
	var red = $Node/Red
	$Node.remove_child(red)
	$Node.add_child(red)
	$Node.remove_child(red)
	add_child(red);

and inserting another idle_frame between the first add_child and the second remove_child fixes it again... but I don't know why such a thing would be necessary.

In my full program I have observed that the node appears initially with the correct drawing order, but seemingly irrelevant changes made elsewhere in the tree cause it to jump out of order, and other irrelevant changes would put it back in the right draw order. It's incredibly fickle, but easily reproducible.

@kleonc
Copy link
Member

kleonc commented Jul 19, 2022

I couldn't tell you what the difference is, but I am certain the problem stopped happening when I changed the type of the initial parent (an autoload) from Node to Control.

Control extends CanvasItem, contrary to Node. I'd guess that's what makes the difference.

And indeed, if you'd change the type of "Node" node in your MRP from Node to Node2D the issue goes away (without deferring any calls):

Node Node2D
image Godot_v3 4 4-stable_win64_s7HGzx6hIo

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.

4 participants