godotengine / godot-proposals

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

Define and expose an Inspector-like property list editor to the scripting API #123

Open willnationsdev opened 5 years ago

willnationsdev commented 5 years ago

Describe the project you are working on: I have worked on GUIs for the editor, but my issue applies equally to any game that includes an Options page, Settings page, or similar. It also applies to Godot "games" that are tools of which there is a growing and vibrant community.

Describe the problem or limitation you are having in your project: The Godot Editor has a built-in system for generating an Inspector that allows one to edit the data associated with an Object. However, there is no capacity for taking advantage of this existing system to generate such Inspectors for one's own plugins, standalone tools, or in-game GUI elements.

Yes, you can often times just delegate things to the EditorInspector, but 1) that only applies to plugins, not external tools or game GUIs and 2) it limits users' ability to control their user experience by forcing them to either rely on the Inspector or re-implement existing Inspector functionality for a local GUI.

Some use cases, even inside the editor, are better when they avoid working with the Inspector. For example, creating editable fields inside VisualScript's GraphNodes for the editor. If you could generate a GUI that looks and behaves exactly like the Inspector, but is present inside the graph node and affects that object directly, then there'd be a lot less work involved in creating Inspector-less, more streamlined user experiences for VisualScript and visual graph shaders in general (much like Unreal's Blueprint). The same goes for creating editable GUI fields in a variety of other contexts, both in and out of the editor.

Describe how this feature / enhancement will help you overcome this problem or limitation:

This change would enable users to quickly and consistently create a high-quality editing experience that mimics the features, quality assurance, and robustness of the official Godot Editor Inspector, but with the flexibility to put the editable fields anywhere they want and to target whatever object they want.

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:

# Sample 1
# Can create a Form object and get an Array of FormProperty node instances
# Default behavior runs off of the object's property list.
var form = Form.new()
form.object = $Options
var form_properties: Array = form.create_form_properties()

# Sample 2
# can add FormProperty objects to VBoxContainer for an Inspector-like editor.
# - "Main" Node (this script)
#     - "Options" ScrollContainer (options.gd)
#         - VBoxContainer <- add all FormProperty nodes to this node.
for a_form_property in form_properties:
    $Options/VBoxContainer.add_child(a_form_property)

# Sample 3
# Can register new FormProperty types using Scripts that extend the type.
# They would have a virtual method that decides whether they apply to a given PropertyInfo.
# The first matching result, processed from last to first, would get used.
form.register_form_property(load("my_custom_form_property.gd"))

# Sample 4
# I can override what property list is used to draw data from the assigned Object.
form.set_object_properties([ { "name": "hi", "type": TYPE_STRING } ])

# Sample 5
# I can receive a signal callback for whenever a value is edited by the Form
form.connect("property_edited", self, "_on_property_edited")

# Sample 6
# The editor would, for usability purposes, provide a Node that can generate a form
# and vertically or horizontally align it as desired.
var form_container = FormContainer.new()
form_container.target = @"Options" # an exported property
add_child(form_container) # is a Node itself.

Below is a would-be options menu (poorly made, w/e). I would ideally have a horizontally-aligned FormContainer for the top section and two vertically-aligned FormContainers for the two bottom sections.

options_page

The point being that I don't have to write the form creation/hookup code myself, nor do I have to write sophisticated editors for Godot's existing resource types. I can focus on building my game/tool.

Then, if I wanted to arrange the UI however I want for a more complex title, I can use the Form class directly and do whatever I want with the FormProperty nodes. The example below could be a game that uses a diagonal, custom-aligned set of properties on a page that, regardless, all provide editors for modifying a single object's data in an easy manner.

persona_5_settings_menu (Yes, this is a settings menu from Persona 5)

If it were just about changing the visualization of the boolean form editor, then the user could just define their own custom FormProperty that actually displays the boolean as an on/off switch, as above, and then override the Form's use of TYPE_BOOL properties to use that FormProperty instead.

Describe implementation detail for your proposal (in code), if possible:

  1. Define a non-editor Inspector class called Form to avoid confusion with the EditorInspector.
  2. Refactor EditorProperty types to be FormProperty types instead. If necessary, define editor-specific classes that make use of the core FormProperty types, but I think that should be minimized.
  3. Refactor the EditorInspector to use the Form class.
  4. (the most complex part) identify the best way of organizing the Godot Engine project so that EditorProperty types can be available to both the engine and the editor.
    1. You could just move them all into the core (considered bloat?).
    2. You could make a symlink to the modules directly and end up having them defined in one place, but built in two: the editor and the modules (weird, unconventional, but would solve synchronization issues between two parts of the codebase - might have cross-platform issues due to differences in symlink APIs though).
    3. You could make them all a first-party addon that is somehow also available to the Inspector. In this case, the Inspector would need to support plugging in user-defined EditorProperty-turned-FormProperty types. And the editor would have to somehow download and use these types in the editor, perhaps even without showing up in the FileSystem.
      • This would be especially problematic for people with poor Internet connections and would also lead to less than ideal UX since the editor would ship with diminished functionality until it is able to separately install these things.

No matter how I look at it, the cleanest solution is just to move them to core, but I'm open to other suggestions.

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

I would use this every single day since I mess with plugin code all the time, and plugins often have their own data with their own GUI for viewing and editing that data.

It would also enable us to simplify and refactor several other parts of the Godot editor I imagine. VisualScript and VisualShader nodes are one place. Anything in a dock, bottom panel, or viewport is another. Several uses of Tree could probably be replaced entirely to use this more robust, pluggable tool.

Tons and tons of games would be able to use this to vastly simplify their code.

Non-game applications would make heavy use of this as they often involve users entering or configuring data and gaining some benefit from allowing the app to have that data.

The code is all inside the editor. You could re-implement the entire Inspector as an addon but that would be a highly involved and complex process, not to mention a waste of time since you'd then have to maintain the codebase to closely match the editor's code for consistency's sake. It would really be a bad idea to do that. And having to go through the effort of coding one's own form for general purpose stuff is a huge time sink when there is already a perfectly good form/inspector built and maintained by the community.

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

As outlined above, making this an addon presents huge synchronization/maintenance hazards. In addition, if you updated the Editor to use an addon, then it would make for horrible UX. In my opinion, core is really the best place for it.

If the devs believe that including it in core would be too much bloat, then I would believe that at least some kind of partial solution is best where some essential form/form properties are kept in core and then more are kept maintained in the editor AND in a separate downloadable addon, so that those who want to build godot "games" that are tools with complex editors required could still make use of this API. Not sure of the best way to do that though.

willnationsdev commented 5 years ago

Related to #13. Probably would supercede #97, or at the very least, make implementing it a lot easier.

m21-cerutti commented 8 months ago

For those who were searching to how to make an in game inspector like ui, found this repository. https://github.com/4d49/object-inspector Not handling the array for now, but this solution it was exactly what I would want for this feature, allowing to have or construct inspector in game.