godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.17k stars 98 forks source link

Add support for hidden Editable Children #11186

Open allenwp opened 1 week ago

allenwp commented 1 week ago

Describe the project you are working on

Any project.

Describe the problem or limitation you are having in your project

Editable Children can cause clutter in the Scene tree by exposing many nodes that may not be relevant for overriding. This makes accidental overriding easier, but also makes it harder to find the nodes that you typically would want to override.

This problem becomes a larger issue when creating plugins: The plugin author may have a complex node and intends users to only interface with certain editable children, not all of the children of their packed scene. Because editable children shows all children, it is easy for the plugin to be misused or confusing to the user.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Hidden editable children allows authors of packed scenes to hide nodes that shouldn't be normally be visible to the user of the packed scene. By giving control to the author of the packed scene over which nodes are hidden or not, the existing Editable Children feature can be used more easily and safely, while also reducing clutter in scenes that use the packed scene.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Before:

current-editable-children

With Hidden Editable Children:

hidden-editable-children

Usage

usage

Showing Hidden Editable Children:

Hidden Editable Children can still be shown to provide greater customization of a packed scene instance when needed: show-hidden

This effectively brings back the existing Editable Children functionality, but only when needed: hidden-children-shown

It is possible to Show Hidden Editable Children, make a change to a hidden child, and then re-hide them. This is intentional as an advanced feature that some users would make use of to keep their scene tree free of clutter, while maintaining full editable children functionality. Because this is a multi-step process that must be performed by the user, I expect that there should not be any usability issues surrounding this.

Implementation

It's possible that this proposal could be implemented without any changes to core/runtime functionality of the game engine; only editor changes would be made by making use of Node metadata.

When selecting "Hide in Editable Children", the editor will add one metadata item to that node:

[node name="HiddenNodeClutter" type="Node2D" parent="."]
metadata/_hide_in_editable_children_ = true

When selecting "Show Hidden Editable Children", the editor will add one metadata item to that node:

[node name="PackedScene" parent="." instance=ExtResource("1_ig7tw")]
metadata/_show_hidden_editable_children_ = true

I haven't worked with the Scene tree code, so I'm not sure what the exact scope of work would be for this.

If this enhancement will not be used often, can it be worked around with a few lines of script?

This requires changes to the Scene tree.

Is there a reason why this should be core and not an add-on in the asset library?

This requires changes to the Scene tree.

allenwp commented 1 week ago

What if you added a node under editable child and then it gets hidden? What will be the parent of such node? (with current implementation of hiding, the whole sub-tree will be invisible, including the node that isn't part of the instance) [source]

That's a good point. Maybe an ideal would be that any node that has changes and all of its parents must be always be visible, regardless of hidden state. See the first Label as an example:

edited-hidden-node

This part might be especially tricky to implement(?)

timoschwarzer commented 1 week ago

As you have outlined here, the feature that PR is providing (exposing specific nodes from a scene) could be seen as what the Editable Children feature should have been in the first place.

As far as I can see, the main motivation behind this proposal is to provide an alternative approach to that PR that builds upon the existing Editable Children feature.

Having a web development background, I have had my fair share of experience with componentization of tree structures (web frameworks are nothing else really :smile: ) and I must admit that the approach of this proposal does feel unnatural and impractical to me, mostly because of its "Nodes are editable by default and I have to hide it" nature.

In most components there are only a small number of "Slots" (exposed nodes in Godot). Needing to enable Editable Children and then excluding almost all nodes from being visible in Exposed Children feels like extra steps with much room for mistakes (e.g. adding a new Node and forgetting to hide it).

As a Godot user I'd much rather have a solution that allows for explicit exposure of child Nodes in parallel to Editable Children than a feature that builds upon Editable Children but provides me a much worse UX.

KoBeWi commented 1 week ago

Another thing is that node slots are exposed by default, while with hiding feature you have to enable editable children manually on every instance just to show one desired node.

huwpascoe commented 1 week ago

I wasn't gonna share this outside of devchat, but the author said I should... so I will now communicate

in the form of interpretive code

Status Quo

Not great, not terrible.

class MyPackedScene {
protected:
    Node* exposed_node;
    Node* implementation_node_a;
    Node* implementation_node_b;
};

The PR

Nice.

class MyPackedScene {
public:
    Node* exposed_node;
protected:
    Node* implementation_node_a;
    Node* implementation_node_b;
};

This proposal

Going above and beyond to appease maintainers, resulting in something that's actually worse than before.

class MyPackedScene {
public:
    // no >:(
protected:
    Node* exposed_node;
    [[extra_hidden]] Node* implementation_node_a;
    [[extra_hidden]] Node* implementation_node_b;
};
CarpenterBlue commented 6 days ago

Would it be possible to leverage Groups or Meta for this instead?