Creando plugins

Acerca de los plugins

A plugin is a great way to extend the editor with useful tools. It can be made entirely with GDScript and standard scenes, without even reloading the editor. Unlike modules, you don’t need to create C++ code nor recompile the engine. While this makes plugins less powerful, there are still many things you can do with them. Note that a plugin is similar to any scene you can already make, except it is created using a script to add editor functionality.

Este tutorial te guiará a través de la creación de dos sencillos plugins para que puedas entender cómo funcionan y ser capaz de desarrollar los tuyos propios. El primero será un nodo personalizado que puede añadir a cualquier escena del proyecto y el otro será un panel personalizado añadido al editor.

Creando un plugin

Antes de empezar, crea un proyecto vacío nuevo donde quieras. Esto servirá como base para desarrollar y probar los plugins.

The first thing you need for the editor to identify a new plugin is to create two files: a plugin.cfg for configuration and a tool script with the functionality. Plugins have a standard path like addons/plugin_name inside the project folder. Godot provides a dialog for generating those files and placing them where they need to be.

In the main toolbar, click the Project dropdown. Then click Project Settings.... Go to the Plugins tab and then click on the Create button in the top-right.

You will see the dialog appear, like so:

../../../_images/making_plugins-create_plugin_dialog.png

The placeholder text in each field describes how it affects the plugin’s creation of the files and the config file’s values.

To continue with the example, use the following values:

Plugin Name: My Custom Node
Subfolder: my_custom_node
Description: A custom node made to extend the Godot Engine.
Author: Your Name Here
Version: 1.0.0
Language: GDScript
Script Name: custom_node.gd
Activate now: No

You should end up with a directory structure like this:

../../../_images/making_plugins-my_custom_mode_folder.png

plugin.cfg is a simple INI file with metadata about your plugin. The name and description help people undersatnd what it does. Your name helps you get properly credited for your work. The version number helps others know if they have an outdated version; if you are unsure on how to come up with the version number, check out Semantic Versioning. The main script file will instruct Godot what your plugin does in the editor once it is active.

The script file

Upon creation of the plugin, the dialog will automatically open the EditorPlugin script for you. The script has two requirements that you cannot change: it must be a tool script, or else it will not load properly in the editor, and it must inherit from class_EditorPlugin.

It’s important to deal with initialization and clean-up of resources. A good practice is to use the virtual function _enter_tree() to initialize your plugin and _exit_tree() to clean it up. Thankfully, the dialog generates these callbacks for you. Your script should look something like this:

tool
extends EditorPlugin

func _enter_tree():
    # Initialization of the plugin goes here
    pass

func _exit_tree():
    # Clean-up of the plugin goes here
    pass
#if TOOLS
using Godot;
using System;

[Tool]
public class CustomNode : EditorPlugin
{
    public override void _EnterTree()
    {
        // Initialization of the plugin goes here
    }

    public override void _ExitTree()
    {
        // Clean-up of the plugin goes here
    }
}
#endif

This is a good template to use when creating new plugins.

A custom node

Sometimes you want a certain behavior in many nodes, such as a custom scene or control that can be reused. Instancing is helpful in a lot of cases, but sometimes it can be cumbersome, especially if you’re using it in many projects. A good solution to this is to make a plugin that adds a node with a custom behavior.

Advertencia

Nodes added via an EditorPlugin are «CustomType» nodes. While they work with any scripting language, they have fewer features than the Script Class system. If you are writing GDScript or NativeScript, we recommend using them instead.

To create a new node type, you can use the function add_custom_type() from the class_EditorPlugin class. This function can add new types to the editor (nodes or resources). However, before you can create the type, you need a script that will act as the logic for the type. While that script doesn’t have to use the tool keyword, it can be added so the script runs in the editor.

For this tutorial, we’ll create a simple button that prints a message when clicked. For that, we’ll need a simple script that extends from class_Button. It could also extend class_BaseButton if you prefer:

tool
extends Button

func _enter_tree():
    connect("pressed", self, "clicked")

func clicked():
    print("You clicked me!")
using Godot;
using System;

[Tool]
public class MyButton : Button
{
    public override void _EnterTree()
    {
        Connect("pressed", this, "clicked");
    }

    public void clicked()
    {
        GD.Print("You clicked me!");
    }
}

That’s it for our basic button. You can save this as my_button.gd inside the plugin folder. You’ll also need a 16×16 icon to show in the scene tree. If you don’t have one, you can grab the default one from the engine and save it in your addons/my_custom_node folder as icon.png, or use the default Godot logo (preload(«res://icon.png»)). You can also use SVG icons if desired.

../../../_images/making_plugins-custom_node_icon.png

Now, we need to add it as a custom type so it shows on the Create New Node dialog. For that, change the custom_node.gd script to the following:

tool
extends EditorPlugin

func _enter_tree():
    # Initialization of the plugin goes here
    # Add the new type with a name, a parent type, a script and an icon
    add_custom_type("MyButton", "Button", preload("my_button.gd"), preload("icon.png"))

func _exit_tree():
    # Clean-up of the plugin goes here
    # Always remember to remove it from the engine when deactivated
    remove_custom_type("MyButton")
#if TOOLS
using Godot;
using System;

[Tool]
public class CustomNode : EditorPlugin
{
    public override void _EnterTree()
    {
        // Initialization of the plugin goes here
        // Add the new type with a name, a parent type, a script and an icon
        var script = GD.Load<Script>("MyButton.cs");
        var texture = GD.Load<Texture>("icon.png");
        AddCustomType("MyButton", "Button", script, texture);
    }

    public override void _ExitTree()
    {
        // Clean-up of the plugin goes here
        // Always remember to remove it from the engine when deactivated
        RemoveCustomType("MyButton");
    }
}
#endif

With that done, the plugin should already be available in the plugin list in the Project Settings, so activate it as explained in Checking the results.

Then try it out by adding your new node:

../../../_images/making_plugins-custom_node_create.png

When you add the node, you can see that it already has the script you created attached to it. Set a text to the button, save and run the scene. When you click the button, you can see some text in the console:

../../../_images/making_plugins-custom_node_console.png

Un panel personalizado

Algunas veces necesitarás ampliar el editor y añadir herramientas que estén siempre disponibles. Una forma fácil de hacerlo es añadir un nuevo panel con un plugin. Los paneles son sólo escenas basadas en Control, estas son creadas de una manera similar a las escenas GUI comunes.

Creating a custom dock is done just like a custom node. Create a new plugin.cfg file in the addons/my_custom_dock folder, then add the following content to it:

[plugin]

name="My Custom Dock"
description="A custom dock made so I can learn how to make plugins."
author="Your Name Here"
version="1.0"
script="custom_dock.gd"
[plugin]

name="My Custom Dock"
description="A custom dock made so I can learn how to make plugins."
author="Your Name Here"
version="1.0"
script="CustomDock.cs"

Then create the script custom_dock.gd in the same folder. Fill it with the template we’ve seen before to get a good start.

Dado que estamos intentando añadir un nuevo panel personalizado, necesitamos crear el contenido de dicho panel. Esto no es más que una escena estándar de Godot. sólo crea una nueva escena y luego editarla.

Para un panel del editor, la raíz de la escena debe ser un Control o una de sus clases derivadas. Para este tutorial, puedes hacer un solo botón. El nombre del nodo raíz también será el nombre que aparezca en la pestaña del panel, así que asegúrate de poner uno descriptivo pero corto. No olvides añadir un texto a tu botón.

../../../_images/making_plugins-my_custom_dock_scene.png

Guarda la escena como my_dock.tscn. Ahora necesitas seleccionar la escena que creaste y añadirla como un panel en el editor. Para ello puedes usar la función add_control_to_dock() de la clase EditorPlugin.

Necesitas seleccionar una posición de panel para añadirlo y tener un Control para añadir (que es la escena que acabas de crear). No olvides quitar el panel cuando el plugin es desactivado. El código debería verse así:

tool
extends EditorPlugin

# A class member to hold the dock during the plugin life cycle
var dock

func _enter_tree():
    # Initialization of the plugin goes here
    # Load the dock scene and instance it
    dock = preload("res://addons/my_custom_dock/my_dock.tscn").instance()

    # Add the loaded scene to the docks
    add_control_to_dock(DOCK_SLOT_LEFT_UL, dock)
    # Note that LEFT_UL means the left of the editor, upper-left dock

func _exit_tree():
    # Clean-up of the plugin goes here
    # Remove the dock
    remove_control_from_docks(dock)
     # Erase the control from the memory
    dock.free()
#if TOOLS
using Godot;
using System;

[Tool]
public class CustomDock : EditorPlugin
{
    Control dock;

    public override void _EnterTree()
    {
        dock = (Control)GD.Load<PackedScene>("addons/my_custom_dock/my_dock.tscn").Instance();
        AddControlToDock(DockSlot.LeftUl, dock);
    }

    public override void _ExitTree()
    {
        // Clean-up of the plugin goes here
        // Remove the dock
        RemoveControlFromDocks(dock);
        // Erase the control from the memory
        dock.Free();
    }
}
#endif

Note that, while the dock will initially appear at its specified position, the user can freely change its position and save the resulting layout.

Checking the results

It’s now time to check the results of your work. Open the Project Settings and click on the Plugins tab. Your plugin should be the only one on the list. If it is not showing, click on the Update button in the top-right corner.

../../../_images/making_plugins-project_settings.png

En la columna Estado, puedes ver que el plugin está inactivo, debes hacer clic en el estado para seleccionar Activo. El panel debe ser visible inmediatamente, incluso antes de cerrar la ventana de configuración. Ahora deberías tener un panel personalizado:

../../../_images/making_plugins-custom_dock.png

Going beyond

Now that you’ve learned how to make basic plugins, you can extend the editor in several ways. Lots of functionality can be added to the editor with GDScript; it is a powerful way to create specialized editors without having to delve into C++ modules.

You can make your own plugins to help yourself and share them in the Asset Library so that people can benefit from your work.