Создание плагинов

О плагинах

Плагин является отличным способом расширить возможности редактора новыми полезными инструментами. Его можно создать используя лишь GDScript и стандартные сцены, без необходимости перезапускать редактор. В отличие от модулей, вам не надо писать код на C++ или заново компилировать движок. Это делает плагины менее эффективными, но благодаря им можно делать многие вещи. Обратите внимание что плагин схож с любой сценой, которые вы уже делали, исключая то, что он создается используя скрипт для добавления функционала редактора.

В этом руководстве вы научитесь создавать два плагина, чтобы понять, как они работают, и разработать свой собственный. Первый — это настраиваемый узел, который можно добавить в любую сцену проекта, а второй — настраиваемый док-модуль, добавляемый в редактор.

Создаем плагин

Перед тем, как начать, создайте новый пустой проект в любом месте. Это послужит базой для разработки и тестирования плагинов.

Чтобы редактор мог распознать новый плагин, первым делом нужно создать два файла: plugin.cfg для конфигурации и скрипт инструмента с необходимым функционалом. У плагинов есть стандартный путь типа addons/plugin_name внутри папки проекта. Godot предоставляет диалоговое окно для генерации этих файлов и их размещения в нужном месте.

На главной панели инструментов нажмите раскрывающийся список Project. Затем нажмите Project Settings.... Перейдите на вкладку Plugins и нажмите кнопку Create New Plugin в правом верхнем углу.

Появится диалоговое окно, похожее на это:

../../../_images/making_plugins-create_plugin_dialog.webp

Текст-заполнитель в каждом поле описывает, как он влияет на создание файлов плагином и значения файла конфигурации.

Чтобы продолжить пример, используйте следующие значения:

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

Предупреждение

Снятие флажка Activate now? в C# обязательно, поскольку, как и любой другой скрипт C#, скрипт EditorPlugin требует компиляции, что требует сборки проекта. После сборки проекта плагин можно включить на вкладке Plugins в разделе Project Settings.

В конечном итоге вы должны получить такую структуру каталогов, как эта:

../../../_images/making_plugins-my_custom_mode_folder.webp

plugin.cfg — это INI-файл с метаданными о вашем плагине. Название и описание помогают людям понять, что он делает. Ваше имя помогает вам получить должное признание за вашу работу. Номер версии помогает другим пользователям определить, установлена ли у них устаревшая версия; если вы не знаете, как определить номер версии, ознакомьтесь с разделом Семантическое версионирование. Основной файл скрипта будет указывать Godot, что ваш плагин делает в редакторе после активации.

Файл cкрипта

После создания плагина диалоговое окно автоматически откроет скрипт EditorPlugin. Скрипт имеет два требования, которые нельзя изменить: он должен быть скриптом @tool, иначе он не будет корректно загружен в редакторе, и должен наследовать класс EditorPlugin.

Предупреждение

Помимо скрипта EditorPlugin, любой другой GDScript, используемый вашим плагином, также должен быть инструментом. Любой GDScript без @tool, используемый редактором, будет работать как пустой файл!

Важно заниматься инициализацией и очисткой ресурсов. Рекомендуется использовать виртуальную функцию _enter_tree() для инициализации плагина и _exit_tree() для его очистки. К счастью, диалоговое окно генерирует эти обратные вызовы автоматически. Ваш скрипт должен выглядеть примерно так:

@tool
extends EditorPlugin


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


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

Это хороший шаблон для использования при создании новых плагинов.

Пользовательский Узел (node)

Иногда требуется определённое поведение для многих узлов, например, для пользовательской сцены или элемента управления, которые можно использовать повторно. Инстансирование полезно во многих случаях, но иногда оно может быть обременительным, особенно если вы используете его во многих проектах. Хорошее решение — создать плагин, добавляющий узел с пользовательским поведением.

Предупреждение

Узлы, добавляемые через EditorPlugin, относятся к типу "CustomType". Хотя они работают с любым языком скриптов, их функционал ограничен, чем у the Script Class system. Если вы пишете код на GDScript или NativeScript, мы рекомендуем использовать классы скриптов.

Чтобы создать новый тип узла, можно использовать функцию add_custom_type() из класса EditorPlugin. Эта функция добавляет новые типы в редактор (узлы или ресурсы). Однако, прежде чем создать тип, необходим скрипт, который будет выполнять логику для этого типа. Хотя этот скрипт не обязательно должен использовать аннотацию @tool, её можно добавить, чтобы скрипт запускался в редакторе.

В этом уроке мы создадим кнопку, которая выводит сообщение при нажатии. Для этого нам понадобится скрипт, наследующий класс Button. Он также может наследовать класс BaseButton, если вам так удобнее:

@tool
extends Button


func _enter_tree():
    pressed.connect(clicked)


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

Вот и всё с нашей базовой кнопкой. Вы можете сохранить её как my_button.gd в папке плагина. Вам также понадобится значок размером 16×16 для отображения в дереве сцены. Если у вас его нет, вы можете взять стандартный значок из движка и сохранить его в папке addons/my_custom_node как icon.png, или использовать стандартный логотип Godot (preload("res://icon.svg")).

Совет

Изображения SVG, используемые в качестве пользовательских значков узлов, должны иметь включённые параметры импорта Editor > Scale With Editor Scale и Editor > Convert Colors With Editor Themeimport options. Это позволит значкам следовать настройкам масштаба и темы редактора, если они разработаны с той же цветовой палитрой, что и собственные значки Godot.

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

Теперь нам нужно добавить его как пользовательский тип, чтобы он отображался в диалоговом окне Create New Node. Для этого измените скрипт custom_node.gd следующим образом:

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

После этого плагин уже должен быть доступен в списке плагинов в Project Settings, поэтому активируйте его, как описано в разделе Checking the results.

Затем попробуйте добавить новый узел:

../../../_images/making_plugins-custom_node_create.webp

При добавлении узла вы увидите, что к нему уже прикреплён созданный вами скрипт. Задайте текст для кнопки, сохраните и запустите сцену. При нажатии на кнопку в консоли появится текст:

../../../_images/making_plugins-custom_node_console.webp

Пользовательский док

Иногда требуется расширить редактор и добавить инструменты, которые всегда доступны. Самый простой способ сделать это — добавить новый док с помощью плагина. Доки — это всего лишь сцены, основанные на Control, поэтому они создаются аналогично обычным сценам графического интерфейса.

Создание пользовательского дока выполняется так же, как создание пользовательского узла. Создайте новый файл plugin.cfg в папке addons/my_custom_dock и добавьте в него следующее содержимое:

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

Затем создайте скрипт custom_dock.gd в той же папке. Заполните его шаблоном template we've seen before, (который мы видели ранее) чтобы начать.

Поскольку мы пытаемся добавить новый пользовательский док, нам нужно создать его содержимое. Это всего лишь стандартная сцена Godot: просто создайте новую сцену в редакторе и отредактируйте её.

Для док-станции редактора корневой узел должен быть Control или одним из его дочерних классов. В этом руководстве вы можете создать одну кнопку. Имя корневого узла будет также отображаться на вкладке док-станции, поэтому обязательно дайте ему короткое и описательное имя. Также не забудьте добавить текст к кнопке.

../../../_images/making_plugins-my_custom_dock_scene.webp

Сохраните эту сцену как my_dock.tscn. Теперь нам нужно загрузить созданную сцену и добавить её в качестве док-панели в редакторе. Для этого можно использовать функцию add_control_to_dock() из класса EditorPlugin.

Вам нужно выбрать позицию док-станции и определить добавляемый элемент управления (то есть только что созданную вами сцену). Не забудьте удалить док-станцию после деактивации плагина. Скрипт может выглядеть так:

@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 instantiate it.
    dock = preload("res://addons/my_custom_dock/my_dock.tscn").instantiate()

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

Обратите внимание, что, хотя изначально док-панель будет отображаться в указанном положении, пользователь может свободно изменить ее положение и сохранить полученный макет.

Проверка результатов

Теперь пора проверить результаты вашей работы. Откройте Project Settings и перейдите на вкладку Plugins. Ваш плагин должен быть единственным в списке.

../../../_images/making_plugins-project_settings.webp

Видите, плагин не включён. Установите флажок Enable, чтобы активировать плагин. Док должен стать видимым ещё до того, как вы закроете окно настроек. Теперь у вас должен быть настроенный док:

../../../_images/making_plugins-custom_dock.webp

Регистрация автозагрузок/синглетонов в плагинах

Плагины редактора могут автоматически регистрировать autoloads при включении плагина. Это также включает отмену регистрации автозагрузки при отключении плагина.

Это ускоряет настройку плагинов для пользователей, поскольку им больше не придется вручную добавлять автозагрузки в настройки своего проекта, если плагин вашего редактора требует использования автозагрузки.

Используйте следующий код для регистрации синглтона из плагина редактора:

@tool
extends EditorPlugin

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


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


func _disable_plugin():
    remove_autoload_singleton(AUTOLOAD_NAME)

Использование под-плагинов

Часто плагин добавляет несколько функций, например, настраиваемый узел и панель. В таких случаях может быть проще создать отдельный скрипт плагина для каждой из этих функций. Для этого можно использовать под-плагины.

Сначала создайте все плагины и подплагины как обычные плагины:

../../../_images/sub_plugin_creation.webp

Затем переместите подплагины в основную папку плагинов:

../../../_images/sub_plugin_moved.webp

Godot скроет подплагины из списка плагинов, чтобы пользователь не мог их включить или отключить. Вместо этого основной скрипт плагина должен включать и отключать подплагины следующим образом:

@tool
extends EditorPlugin

# The main plugin is located at res://addons/my_plugin/
const PLUGIN_NAME = "my_plugin"

func _enable_plugin():
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/node", true)
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/panel", true)

func _disable_plugin():
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/node", false)
    EditorInterface.set_plugin_enabled(PLUGIN_NAME + "/panel", false)

Выходя за рамки

Теперь, когда вы научились создавать базовые плагины, вы можете расширить возможности редактора несколькими способами. GDScript позволяет расширить функциональность редактора; это мощный способ создания специализированных редакторов без необходимости углубляться в изучение модулей C++.

Вы можете создавать собственные плагины, которые помогут вам, и делиться ими в Asset Library, чтобы люди могли извлечь пользу из вашей работы.