Создание плагинов
О плагинах
Плагин является отличным способом расширить возможности редактора новыми полезными инструментами. Его можно создать используя лишь GDScript и стандартные сцены, без необходимости перезапускать редактор. В отличие от модулей, вам не надо писать код на C++ или заново компилировать движок. Это делает плагины менее эффективными, но благодаря им можно делать многие вещи. Обратите внимание что плагин схож с любой сценой, которые вы уже делали, исключая то, что он создается используя скрипт для добавления функционала редактора.
В этом руководстве вы научитесь создавать два плагина, чтобы понять, как они работают, и разработать свой собственный. Первый — это настраиваемый узел, который можно добавить в любую сцену проекта, а второй — настраиваемый док-модуль, добавляемый в редактор.
Создаем плагин
Перед тем, как начать, создайте новый пустой проект в любом месте. Это послужит базой для разработки и тестирования плагинов.
Чтобы редактор мог распознать новый плагин, первым делом нужно создать два файла: plugin.cfg для конфигурации и скрипт инструмента с необходимым функционалом. У плагинов есть стандартный путь типа addons/plugin_name внутри папки проекта. Godot предоставляет диалоговое окно для генерации этих файлов и их размещения в нужном месте.
На главной панели инструментов нажмите раскрывающийся список Project. Затем нажмите Project Settings.... Перейдите на вкладку Plugins и нажмите кнопку в правом верхнем углу.
Появится диалоговое окно, похожее на это:
Текст-заполнитель в каждом поле описывает, как он влияет на создание файлов плагином и значения файла конфигурации.
Чтобы продолжить пример, используйте следующие значения:
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
Plugin Name: My Custom Node
Subfolder: MyCustomNode
Description: A custom node made to extend the Godot Engine.
Author: Your Name Here
Version: 1.0.0
Language: C#
Script Name: CustomNode.cs
Activate now: No
Предупреждение
Снятие флажка Activate now? в C# обязательно, поскольку, как и любой другой скрипт C#, скрипт EditorPlugin требует компиляции, что требует сборки проекта. После сборки проекта плагин можно включить на вкладке Plugins в разделе Project Settings.
В конечном итоге вы должны получить такую структуру каталогов, как эта:
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
#if TOOLS
using Godot;
[Tool]
public partial 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
Это хороший шаблон для использования при создании новых плагинов.
Пользовательский Узел (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!")
using Godot;
[Tool]
public partial class MyButton : Button
{
public override void _EnterTree()
{
Pressed += Clicked;
}
public void Clicked()
{
GD.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.
Теперь нам нужно добавить его как пользовательский тип, чтобы он отображался в диалоговом окне 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")
#if TOOLS
using Godot;
[Tool]
public partial 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>("res://addons/MyCustomNode/MyButton.cs");
var texture = GD.Load<Texture2D>("res://addons/MyCustomNode/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
После этого плагин уже должен быть доступен в списке плагинов в Project Settings, поэтому активируйте его, как описано в разделе Checking the results.
Затем попробуйте добавить новый узел:
При добавлении узла вы увидите, что к нему уже прикреплён созданный вами скрипт. Задайте текст для кнопки, сохраните и запустите сцену. При нажатии на кнопку в консоли появится текст:
Пользовательский док
Иногда требуется расширить редактор и добавить инструменты, которые всегда доступны. Самый простой способ сделать это — добавить новый док с помощью плагина. Доки — это всего лишь сцены, основанные на 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"
[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"
Затем создайте скрипт custom_dock.gd в той же папке. Заполните его шаблоном template we've seen before, (который мы видели ранее) чтобы начать.
Поскольку мы пытаемся добавить новый пользовательский док, нам нужно создать его содержимое. Это всего лишь стандартная сцена Godot: просто создайте новую сцену в редакторе и отредактируйте её.
Для док-станции редактора корневой узел должен быть Control или одним из его дочерних классов. В этом руководстве вы можете создать одну кнопку. Имя корневого узла будет также отображаться на вкладке док-станции, поэтому обязательно дайте ему короткое и описательное имя. Также не забудьте добавить текст к кнопке.
Сохраните эту сцену как 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()
#if TOOLS
using Godot;
[Tool]
public partial class CustomDock : EditorPlugin
{
private Control _dock;
public override void _EnterTree()
{
_dock = GD.Load<PackedScene>("res://addons/MyCustomDock/MyDock.tscn").Instantiate<Control>();
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
Обратите внимание, что, хотя изначально док-панель будет отображаться в указанном положении, пользователь может свободно изменить ее положение и сохранить полученный макет.
Проверка результатов
Теперь пора проверить результаты вашей работы. Откройте Project Settings и перейдите на вкладку Plugins. Ваш плагин должен быть единственным в списке.
Видите, плагин не включён. Установите флажок Enable, чтобы активировать плагин. Док должен стать видимым ещё до того, как вы закроете окно настроек. Теперь у вас должен быть настроенный док:
Регистрация автозагрузок/синглетонов в плагинах
Плагины редактора могут автоматически регистрировать 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)
#if TOOLS
using Godot;
[Tool]
public partial class MyEditorPlugin : EditorPlugin
{
// Replace this value with a PascalCase autoload name.
private const string AutoloadName = "SomeAutoload";
public override void _EnablePlugin()
{
// The autoload can be a scene or script file.
AddAutoloadSingleton(AutoloadName, "res://addons/MyAddon/SomeAutoload.tscn");
}
public override void _DisablePlugin()
{
RemoveAutoloadSingleton(AutoloadName);
}
}
#endif
Использование под-плагинов
Часто плагин добавляет несколько функций, например, настраиваемый узел и панель. В таких случаях может быть проще создать отдельный скрипт плагина для каждой из этих функций. Для этого можно использовать под-плагины.
Сначала создайте все плагины и подплагины как обычные плагины:
Затем переместите подплагины в основную папку плагинов:
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, чтобы люди могли извлечь пользу из вашей работы.