How to create editor tools in GDScript?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Akien
:warning: Old Version Published before Godot 3 was released.

I know that it’s possible to use the tool keyword in GDScript to create some tools that will extend editor functionalities, as described here: GDScript reference — Godot Engine (latest) documentation in English

However, I have no clue about what can actually be done with it, and how to do it. I’d be glad for some examples of simple tool scripts that extend the editor!

The next logical step up from a tool script will be a plugin script once that feature is finally pushed into a downloadable build. It’s already leaked once so it ought to be fairly soon since the devs did say they were going to push interim quasi-stable builds in advance of the major 2.0.1 release which will be much farther down the line. With tool the script only runs in the editor but with plugin it will also be capable of creating gui nodes that display in the editor, can be interacted with, and have their events connected to the script. At least I would hope they’d extend the gui nodes+connections metaphor consistently for plugin scripts (so it works similar in scripting to how a script handles gui interaction running within a game).

gau_veldt | 2016-03-11 21:31

Don’t forget to reload the project if you make a script a tool.

luislodosm | 2020-10-26 22:45

:bust_in_silhouette: Reply From: rgrams

I just used that to make my own little custom IK setup. It wasn’t really an editor extension, I just needed to calculate and update some objects’ rotations outside the game runtime. It’s pretty awesome to have this feature.

I think a video illustrating this feature would be interesting. I bet that a LOT of users are not even aware of this feature.

Julian Murgia | 2016-02-22 11:32

It’s so simple and yet unlimited it would be hard to make a tutorial. You just write “tool” at the top of a script and it runs in the editor. That’s it.

If users don’t read any of the documentation they’re going to be unaware of a lot of features. The part about tool mode is in the main GDScript doc. Even if you just scroll through reading the headers you can’t miss it.

rgrams | 2016-02-22 12:40

Yes but no, it’s “simple” for people who understand how it works. Personally I understand very well how as script would be executed when my node enters a scene in a game, and what it can impact.

In the editor however, I have no clue. So giving some real examples of scripts should go a long way to expose how “simple” it is :slight_smile:

Akien | 2016-02-22 14:54

:bust_in_silhouette: Reply From: neikeq

There are unlimited examples. This keyword just makes your script run in the editor. It may be mostly used to automate tasks though.

You may want to update the CollisionPolygon2D of a body to automatically match a Polygon2D.

When tools is enabled, the Canvasitem._draw method is also called in the editor, allowing you to preview your drawing code in the canvas editor.

Another example could be automating 9-Slice when drawing tiles on a TileMap. Supposing TileMap emits a signal when the tile data changes (which sadly it doesn’t), I can listen to that signal and update the tile data:

tool
extends TileMap

func _ready():
    connect("tiles_changed", self, "_update_9slice()"

func _update_9slice():
    # All the logic to update the tiles goes here
    update()

You can also use the Scene → Run Script option to run a script in the editor. This requires your script to extends EditorScript and to have tool enabled. You must override the method EditorScript._run and add your logic there (similar to _ready).

Is _draw the only function that gets called in the editor or are the different _process functions called aswell?

umfk | 2016-02-26 16:08

It should call every method like it does in game. If process is enabled, _process(delta) will be called.

neikeq | 2016-02-27 18:04

Are the changes made by those scripts undo-able? Or do we need to call some special function to monitor the changes?

Zylann | 2016-03-12 02:17

Can you give an example of CollisionPolygon2D of a body to automatically match a Polygon2D.
I tried it like this :

export(bool) var Build = 0 setget build_coll

func build_coll(value):
    if has_node("StaticBody2D/CollisionPolygon2D"):
       var coll = get_node("StaticBody2D/CollisionPolygon2D")
       coll.set_polygon(get_polygon())
       coll.update()
       update()

But it updates in the editor but the collisions do not work in game.

kakoeimon | 2016-05-13 10:03

:bust_in_silhouette: Reply From: didier-v

There is an example in my project : https://github.com/didier-v/breakable

The wall scene is a tool. I can and walls in a scene and every time I change their properties (orientation,length, width), the collision shape is updated.

See wall.tcsn and wall.gd

:bust_in_silhouette: Reply From: ndee

Here is a quick tutorial on godots tool mode!
This feature is great to create interactive assets in the editor.

I wish you had this and in text version. Nice job by the way.

kakoeimon | 2016-04-05 08:11