This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+7 votes

I want to export a button that can be clicked in the inspector without having to create an editor plugin. For instance, a "Generate Points" button that will fill an array with random points.

Godot version 3.2.3
in Engine by (12,908 points)

3 Answers

+8 votes
Best answer

Godot currently doesn't expose a way to expose a clickable action within the
Inspector. While you could create an editor plugin, you can also expose a
boolean property with a setter that performs the desired action. The setter
should be made to keep the variable's original value at all times, which means
the checkbox will always remain unchecked. The user will still be able to press
it to trigger the desired action.

The script must be in tool mode for this to work.
Otherwise, the setter won't be run while in the editor.
See Running code in the editor for more information.

This can be useful to create editor tooling when you're in a hurry:

# Notice the setter method.
export var bake_shadows = false setget do_bake_shadows


# In GDScript, setters always need to accept at least one parameter.
# To make it easier to call this method from code, you can make the parameter optional
# by giving it a default value.
func do_bake_shadows(_p_bake_shadows = null):
    print("Do stuff here...")

    # Notice how we never set the variable of `bake_shadows` in this method.
    # Therefore, `bake_shadows` will always remain set to `false` when changed externally.
    # Since exported variables will trigger the setter when modifying the value
    # from the inspector, this `do_bake_shadows()` method will be called
    # whenever the user tries to enable the "Bake Shadows" property.
by (12,908 points)
selected by

One issue I've noticed with this approach is that code changes to the script are not always detected (I'm using an external editor). You can add prints to your setter to verify your changes are detected. Delete the node and re-add it (or detach and attach the script) to force a code refresh.

+2 votes

I too hit this issue so I created EditorScript Launcher. It adds a hotbar with buttons for each of your editor scripts so you can write scripts to speed up your Godot development. Scripts can specify custom UI so you can pass parameters.

After install, you'll get a new "Script Launcher" button on the bottom toolbar that incldues buttons for all of your scripts:
toolbar

While Godot has built-in EditorScript, you have to open them in the code editor to run which means you can't see the scene and can't run when using an external editor.

Scripts look similar to EditorScript but they're static:

tool
extends LaunchableScript

static func run_script(ed: EditorInterface, ui_root: Control):
    var selection := LaunchableScript.get_selection_or_children(ed)
    var name_of_first = selection[0].name.rstrip(" 0123456789")
    for item in selection:
        item.name = name_of_first
by (154 points)
0 votes

C# version (for Godot4) of workaround by Calinou:
When you click checkbox in editor it runs setter with your code and in Editor UI it always be unchecked

using Godot;

[Tool]
public partial class SampleTool : Node3D
{
    [Export]
    public bool ResetPositions
    {
        get => false;
        set
        {
            if (value)
            {
                GD.Print("Resetting positions...");
            }
        }
    }
}
by (14 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.