godot
godot copied to clipboard
GraphEdit get_children() always returns internal child '_connection_layer'
Tested versions
- Reproducible in: 4.3.dev6
- Not reproducible in: 4.3.dev5
System information
Godot v4.3.dev6 - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3080 Ti (NVIDIA; 31.0.15.5176) - AMD Ryzen 5 5600X 6-Core Processor (12 Threads)
Issue description
The get_children() method for GraphEdit node always returns an internal node named '_connection_layer' regardless of the include_internal parameter.
Steps to reproduce
- Create a GraphEdit node.
- Attach a tool script with a _ready() method that prints out the node's children.
- Notice that the output upon loading the scene in the editor contains the child '_connection_layer'.
Minimal reproduction project (MRP)
@Geometror The node's internal flag was removed in https://github.com/godotengine/godot/commit/a81561cbd960d4787ea0dbd68f60f0af67323721 (expand the diff of graph_edit.cpp then go to line 2762).
This is a duplicate of #85005.
From https://github.com/godotengine/godot/pull/88014:
GraphEdit automatically puts frames behind the connection layer
This requires to make the connection layer a non-internal child again (reintroduces https://github.com/godotengine/godot/issues/85005) since there is no better solution at the moment to keep it between background nodes, e.g. frames, and connectable nodes (just modifying the z_index of each node type would mess up the input and is just confusing)
It's sadly a limitation we have to live with for now since we don't allow internal nodes at arbitrary positions (in children), just front and back. GraphEdit is kind of an exotic Control node, which reaches the limits of Godot's UI system.
As a workaround you have to filter out the connection layer by yourself (it has an specific name _connection_layer).
However, the least what we could do is mentioning this in the docs. I know, there were some concerns regarding human-readable unique names for (internal) nodes (#76563), but in this case it's necessary I think. Another admittedly not very ergonomic solution/improvement would be exposing a getter for the (already internally stored) connection layer index. This would would allow implementing a very efficient check for the connection layer which doesn't rely on node names, providing an API which is a bit cleaner.
Thanks for clarifying. I'm curious if there's any plans for a change which would fix this either by lifting the limitations mentioned or by changing how GraphEdit works? After all, just mentioning it in the docs and never addressing it doesn't seem like a permanent fix.
As a stop-gap measure, wouldn't it be better to have get_children() overridden for GraphEdit specifically so that it filters out _connection_layer if include_internal is false? This way, it does not have breaking changes and basic Node rules are respected. This could be removed down the line should the base causes be fixed.
As a workaround you have to filter out the connection layer by yourself (it has an specific name
_connection_layer).
Ah, so we are requiring users to rely on internal node names. Another argument for PR https://github.com/godotengine/godot/pull/76563.