Fazendo plugins

Sobre plugins

Um plug-in é uma ótima maneira de ampliar o editor com ferramentas úteis. Pode ser feito inteiramente com GDScript e cenas padrão, sem precisar recarregar o editor. Ao contrário dos módulos, você não precisa criar código C++ nem recompilar o editor. Embora isso torne os plug-ins menos poderosos, ainda há muitas coisas que você pode fazer com eles. Observe que um plug-in é semelhante a qualquer cena que você já pode criar, exceto que é criado usando um script para adicionar a funcionalidade do editor.

Este tutorial irá guiá-lo através da criação de dois plugins simples para que você possa entender como eles funcionam e ser capaz de desenvolver o seu próprio. O primeiro será um nó personalizado que você pode adicionar a qualquer cena do projeto e o outro será um painel personalizado adicionado ao editor.

Criando um plugin

Antes de começar, crie um novo projeto vazio onde quiser. Isso servirá como base para desenvolver e testar os plugins.

A primeira coisa que você precisa para o editor identificar um novo plugin é criar dois arquivos: um plugin.cfg para configuração e um script de ferramenta com a funcionalidade. Plugins tem um caminho padrão como addons/plugin_name dentro da pasta do projeto. Godot fornece uma caixa de diálogo para gerar esses arquivos e colocá-los onde precisam estar.

Na barra de ferramentas principal, clique no menu suspenso Projeto. Em seguida, clique em Configurações do projeto.... Vá para a guia Plugins e clique no botão Criar no canto superior direito.

Você verá a caixa de diálogo aparecer, assim:

../../../_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.

Para continuar com o exemplo, utilize os seguintes valores:

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

Aviso

Unchecking the Activate now? option in C# is always required because, like every other C# script, the EditorPlugin script needs to be compiled which requires building the project. After building the project the plugin can be enabled in the Plugins tab of Project Settings.

Você deve acabar com uma estrutura de diretório como esta:

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

plugin.cfg é um arquivo INI simples com metadados sobre seu plugin. O nome e a descrição ajudam as pessoas a entender o que ele faz. Seu nome ajuda você a receber os devidos créditos por seu trabalho. O número da versão ajuda outras pessoas a saber se possuem uma versão desatualizada; se você não tiver certeza de como obter o número da versão, verifique Semantic Versioning. O arquivo de script principal instruirá Godot sobre o que seu plug-in faz no editor quando estiver ativo.

O arquivo de script

Após a criação do plugin, a caixa de diálogo abrirá automaticamente o script EditorPlugin para você. O script tem dois requisitos que você não pode alterar: deve ser um script tool, ou então não carregará corretamente no editor, e deve herdar de EditorPlugin.

Aviso

Além do script do EditorPlugin, qualquer outro script usado pelo seu plug-in também deve ser uma ferramenta. * Qualquer GDScript sem tool importado para o editor funcionará como um arquivo vazio! * Qualquer classe C# sem [Tool] não será recarregada quando o projeto for construído, forçando você a reativar o plugin!

É importante lidar com a inicialização e a limpeza dos recursos. Uma boa prática é usar a função virtual _enter_tree() para inicializar seu plugin e _exit_tree() para limpá-lo. Felizmente, a caixa de diálogo gera esses retornos de chamada para você. Seu script deve ficar mais ou menos assim:

tool
extends EditorPlugin


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


func _exit_tree():
    # Clean-up of the plugin goes here.
    pass

Este é um bom modelo para usar ao criar novos plugins.

Um nó personalizado

Às vezes, você deseja um determinado comportamento em muitos nós, como uma cena ou controle personalizado que pode ser reutilizado. A instanciação é útil em muitos casos, mas às vezes pode ser complicada, especialmente se você a estiver usando em muitos projetos. Uma boa solução para isso é criar um plugin que adicione um nó com um comportamento personalizado.

Aviso

Os nós adicionados por meio de um EditorPlugin são nós "CustomType". Embora trabalhem com qualquer linguagem de script, eles têm menos recursos do que o sistema Script Class. Se você estiver escrevendo GDScript ou NativeScript, recomendamos o uso de classes de script.

Para criar um novo tipo de nó, você pode usar a função add_custom_type() da classe EditorPlugin. Esta função pode adicionar novos tipos ao editor (nós ou recursos). No entanto, antes de criar o tipo, você precisa de um script que atue como a lógica do tipo. Embora esse script não precise usar a palavra-chave tool, ela pode ser adicionada para que o script seja executado no editor.

Para este tutorial, criaremos um botão simples que imprime uma mensagem quando clicado. Para isso, vamos precisar de um script simples que se estende de Button. Também pode estender BaseButton se você preferir:

tool
extends Button


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


func clicked():
    print("You clicked me!")

Isso é tudo para o nosso botão básico. Você pode salvá-lo como my_button.gd dentro da pasta do plugin. Você também precisará de um ícone 16×16 para mostrar na árvore de cena. Se você não tiver um, você pode pegar o padrão do mecanismo e salvá-lo em sua pasta addons/my_custom_node como icon.png, ou usar o logotipo Godot padrão (preload("res:// icon.png")). Você também pode usar ícones SVG, se desejar.

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

Agora, precisamos adicioná-lo como um tipo personalizado para que seja exibido na caixa de diálogo Criar Novo Nó. Para isso, altere o script custom_node.gd para o seguinte:

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")

Feito isso, o plugin já deve estar disponível na lista de plugins em Configurações do Projeto, então ative-o conforme explicado em Verificando os resultados.

Em seguida, experimente-o adicionando seu novo nó:

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

Ao adicionar o nó, você pode ver que ele já tem o script que você criou anexado a ele. Defina um texto para o botão, salve e execute a cena. Ao clicar no botão, você pode ver algum texto no console:

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

Um painel personalizado

Às vezes, você precisa estender o editor e adicionar ferramentas que estão sempre disponíveis. Uma maneira fácil de fazer isso é adicionar um novo dock com um plug-in. Docks são apenas cenas baseadas em Control, então elas são criadas de forma semelhante às cenas GUI usuais.

A criação de um painel personalizado é feita exatamente como um nó personalizado. Crie um novo arquivo plugin.cfg na pasta addons/my_custom_dock e adicione o seguinte conteúdo a ele:

[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"

Em seguida, crie o script custom_dock.gd na mesma pasta. Preencha-o com o template que vimos antes para começar bem.

Como estamos tentando adicionar um novo painel personalizado, precisamos criar o conteúdo do painel. Isso nada mais é do que uma cena padrão do Godot: basta criar uma nova cena no editor e editá-la.

Para um painel do editor, o nó raiz deve ser um Control ou uma de suas classes filhas. Para este tutorial, você pode criar um único botão. O nome do nó raiz também será o nome que aparece na guia painel, portanto, certifique-se de fornecer um nome curto e descritivo. Além disso, não se esqueça de adicionar algum texto ao seu botão.

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

Salve esta cena como my_dock.tscn. Agora, precisamos pegar a cena que criamos e adicioná-la como um encaixe no editor. Para isso, você pode contar com a função add_control_to_dock() da classe EditorPlugin.

You need to select a dock position and define the control to add (which is the scene you just created). Don't forget to remove the dock when the plugin is deactivated. The script could look like this:

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()

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

Verificando os resultados

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

You can see the plugin is inactive on the Status column; click on the status to select Active. The dock should become visible before you even close the settings window. You should now have a custom dock:

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

Indo além

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.

Registrando autoloads/singletons em plugins

It is possible for editor plugins to automatically register autoloads when the plugin is enabled. This also includes unregistering the autoload when the plugin is disabled.

This makes setting up plugins faster for users, as they no longer have to manually add autoloads to their project settings if your editor plugin requires the use of an autoload.

Use o seguinte código para registrar um singleton de um plugin de editor:

tool
extends EditorPlugin

# Replace this value with a PascalCase autoload name, as per the GDScript style guide.
const AUTOLOAD_NAME = "SomeAutoload"


func _enter_tree():
    # The autoload can be a scene or script file.
    add_autoload_singleton(AUTOLOAD_NAME, "res://addons/my_addon/some_autoload.tscn")


func _exit_tree():
    remove_autoload_singleton(AUTOLOAD_NAME)