This page has been translated automatically.
Видеоуроки
Interface
Essentials
Advanced
Подсказки и советы
Основы
Программирование на C#
Рендеринг
Professional (SIM)
Принципы работы
Свойства (properties)
Компонентная Система
Рендер
Физика
Редактор UnigineEditor
Обзор интерфейса
Работа с ассетами
Настройки и предпочтения
Работа с проектами
Настройка параметров ноды
Setting Up Materials
Настройка свойств
Освещение
Sandworm
Использование инструментов редактора для конкретных задач
Расширение функционала редактора
Встроенные объекты
Ноды (Nodes)
Объекты (Objects)
Эффекты
Декали
Источники света
Geodetics
World-ноды
Звуковые объекты
Объекты поиска пути
Players
Программирование
Основы
Настройка среды разработки
Примеры использования
C++
C#
UnigineScript
UUSL (Unified UNIGINE Shader Language)
Плагины
Форматы файлов
Materials and Shaders
Rebuilding the Engine Tools
Интерфейс пользователя (GUI)
Двойная точность координат
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
Работа с контентом
Оптимизация контента
Материалы
Визуальный редактор материалов
Сэмплы материалов
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Tutorials
Внимание! Эта версия документация УСТАРЕЛА, поскольку относится к более ранней версии SDK! Пожалуйста, переключитесь на самую актуальную документацию для последней версии SDK.
Внимание! Эта версия документации описывает устаревшую версию SDK, которая больше не поддерживается! Пожалуйста, обновитесь до последней версии SDK.

Расширение функционала редактора

Внимание
Данный функционал является экспериментальным и не рекомендуется для промышленного использования.

UNIGINE позволяет вам расширить базовый функционал UnigineEditor, например, добавить новые меню, окна, команды панели инструментов, подрежимы, определить способ отображения свойств и даже создать собственный редактор. Это стало возможным благодаря Системе плагинов UnigineEditor через добавление пользовательских плагинов .

UnigineEditor — это приложение, полностью написанное на C++, в значительной степени полагающееся на инфраструктуру фреймворка Qt5. Итак, для расширения его функционала требуются не только навыки программирования на C++, но и знакомство с фреймворком Qt5, системой сборки CMake.

Примечание
Для разработки плагинов для UnigineEditor требуется Qt Framework версии 5.12.3. Он не включен в UNIGINE SDK, поэтому вам придется скачать и установить его.

Смотрите также#

Система плагинов редактора#

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

В основном структура системы плагинов выглядит следующим образом:

Plugin System

Система плагинов

Вот краткое описание основных компонентов:

  • QPluginLoader отвечает за загрузку плагинов и предоставление метаданных.
  • Editor::PluginInfo — парсинг и хранение метаданных плагина, взаимодействие с интерфейсом плагина, а также содержит текущее состояние плагина и информацию о возможной ошибке инициализации плагина.
  • Editor::PluginManager — класс-менеджер, отвечающий за поиск плагинов, построение очереди загрузки плагинов, а также загрузку и удаление плагинов.
  • Editor::Plugin — базовый класс, от которого наследуются все плагины Editor, объявляется следующим образом:

    Editor::Plugin Объявление класса

    Исходный код (C++)
    namespace Editor
    {
     
    class EDITOR_API Plugin
    {
    public:
        Plugin();
        virtual ~Plugin();
        // Plugin's life cycle.
        virtual bool init()     = 0;
        virtual void shutdown() = 0;
    };
     
    } // namespace Editor
     
    // Associates the given Identifier (a string literal) to the interface class called Editor::Plugin.
    Q_DECLARE_INTERFACE(Editor::Plugin, "com.unigine.EditorPlugin")

    Он имеет два абстрактных метода, определяющих жизненный цикл , вы должны переопределить их для своего пользовательского плагина:

    • init() — инициализация плагина (возвращает результат инициализации)
    • shutdown() — отключение плагина
    Примечание
    Макрос Q_DECLARE_INTERFACE добавляет интерфейс в метасистему Qt.

Поиск плагинов#

Плагины, библиотеки которых расположены в каталоге, указанном ниже, автоматически загружаются и добавляются в список доступных плагинов UnigineEditor, никакого специального кода не требуется:

  • %project%/bin/editor — для сборки Release и любой сборки SDK.
  • %project%/bin/editor_debug — для сборок Debug на ПК разработчика.

Чтобы увидеть список всех загруженных на данный момент плагинов в UnigineEditor, выберите Help -> Plugins.

Plugins List

Вы можете просмотреть описание любого плагина, выбрав его в списке и нажав Details.

Plugin Details

Если при загрузке плагина произошла ошибка, в окне описания будет отображено ее подробное описание.

Метаданные плагина#

Каждый плагин должен иметь дополнительную информацию, необходимую менеджеру плагинов, чтобы найти ваш плагин и проверить его зависимости перед фактической загрузкой файла библиотеки вашего плагина. Эта информация хранится в метафайле в формате JSON (файл myplugin.json автоматически генерируется при добавлении шаблона плагина Editor в ваш проект) и может быть получена во время выполнения из экземпляра класса Editor::PluginInfo. Этот метафайл может выглядеть следующим образом:

Исходный код
{
    "Name" : "MyPlugin",
    "Vendor" : "Unigine",
    "Description" : "The plugin's description text." ,
    "Version" : "@PLUGIN_VERSION@",
    "CompatVersion" : "@PLUGIN_COMPAT_VERSION@"
    "Dependencies" : [
      {
        "Name": "RequiredPlugin",
        "Type": "required",
        "Version" : "2.9.0.0"
      },
      {
        "Name": "OptionalPlugin",
        "Type": "optional",
        "Version" : "2.8.0"
      }

    ]
}

Вот краткий обзор основных элементов:

  • Name — имя плагина, отображаемое в списке плагинов UnigineEditor и используемое в качестве ссылки при описании зависимостей других плагинов.
  • Vendor, Description — дополнительная информация (необязательно).
  • Version — текущая версия плагина.
  • CompatVersion — последняя бинарно-совместимая версия плагина, определяет, с какой версией этого плагина текущая версия обратно совместима в бинарном режиме, и используется для разрешения зависимостей от этого плагина.
  • Dependencies — список объектов, описывающих зависимости от других плагинов.
  • Name — название плагина, на который опирается этот плагин.
  • Type — тип зависимости, может быть как required, так и optional.
  • Version — версия, с которой должен быть совместим плагин для заполнения зависимости, в виде x.y.z. Может быть пустым, если версия не имеет значения.

На самом деле автор создает файл .json.in, который затем используется CMake для создания фактического файла метаданных плагина .json, заменяя такие переменные, как EDITOR_VERSION, их фактическими значениями.

Зависимости плагинов#

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

Зависимости объявляются с ключом Dependency, который содержит массив объектов JSON с обязательными ключами Name и Version и необязательным ключом Type.

Следующие формулы иллюстрируют, как сопоставляется информация о зависимости. В формулах имя требуемого подключаемого модуля (как определено в Name объекта зависимости) обозначается как DependencyName, а требуемая версия подключаемого модуля обозначается как DependencyVersion. Плагин с указанными Name, Version и CompatVersion, как определено в метаданных плагина, соответствует зависимости, если выполняются следующие условия:

  • Его Name соответствует DependencyName.
  • CompatVersion <= DependencyVersion <= Version

Например, зависимость

Исходный код
{
    "Name" : "SomeOtherPlugin",
    "Version" : "2.4.1"
}

будет соответствовать плагину, который содержит

Исходный код
{
    "Name" : "SomeOtherPlugin",
    "Version" : "3.1.0",
    "CompatVersion" : "2.2.0",
    ...
}

поскольку имя совпадает, а версия 2.4.1, указанная в теге зависимости, находится между 2.2.0 и 3.1.0.

Жизненный цикл плагина#

Чтобы писать плагины для редактора, вы должны понимать шаги, которые выполняет менеджер плагинов при запуске или завершении работы UnigineEditor.

Когда вы запускаете UnigineEditor , менеджер плагинов делает следующее:

  • Ищет в своих путях поиска все динамические библиотеки и считывает их метаданные. Все библиотеки без метаданных и без IID com.unigine.EditorPlugin игнорируются. Начальное состояние всех плагинов — INVALID, так как это первая точка, в которой загрузка плагина при искаженных метаданных в худшем случае может завершиться ошибкой.
  • Создает экземпляр класса Editor::PluginInfo для каждого плагина. Будучи контейнером для метаданных плагина, этот класс также отслеживает текущее состояние плагина. Вы можете получить экземпляры Editor::PluginInfo с помощью функции Editor::PluginManager::plugins().
  • Устанавливает плагины в состояние READ.
  • Проверяет, что зависимости каждого плагина существуют и совместимы.
  • Устанавливает плагины в состояние RESOLVED.
  • Сортирует все плагины в список, называемый «очередью загрузки», где зависимости плагина располагаются после плагина (но не обязательно сразу после него). Это гарантирует, что плагины загружаются и инициализируются в правильном порядке.
  • Загружает библиотеки плагинов и создает их экземпляры Editor::Plugin в порядке очереди загрузки. В этот момент вызываются конструкторы плагинов. Плагины, от которых зависят другие плагины, создаются первыми.
  • Устанавливает плагины в состояние LOADED.
  • Вызывает функции init() всех плагинов в соответствии с очередью загрузки. В функции init() плагин должен убедиться, что все экспортируемые интерфейсы настроены и доступны для других плагинов. Поскольку каждый плагин предполагает, что плагины, от которых он зависит, настроили свои экспортированные интерфейсы.

    Примечание
    Функция init() плагина — хорошее место для:
    • создания новых объектов;
    • загрузки настроек;
    • добавления новых меню и новых действий в них;
    • подключения к сигналам других плагинов.
  • Устанавливает плагины в состояние RUNNING.

При выключении UnigineEditor менеджер плагинов запускает последовательность завершения работы:

  • Вызывает функции shutdown() всех плагинов в порядке очереди загрузки. Плагины должны принимать меры для ускорения фактического завершения работы здесь, например, отключать сигналы, которые в противном случае вызывались бы без необходимости.
  • Уничтожает все плагины, удаляя их экземпляры Editor::Plugin в порядке, обратном очереди загрузки. В этот момент вызываются деструкторы плагинов. Плагины должны убирать за собой, освобождая память и другие ресурсы.

Горячая перезагрузка#

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

  • выгрузить плагин;
  • сделать что-нибудь;
  • перезагрузить плагин.

Вы можете выгрузить и снова загрузить свой плагин, когда это необходимо, с помощью соответствующей кнопки в столбце HotReload (доступно через окно Editor Plugins: Help -> Plugins).

Вы также можете сделать то же самое с помощью кода:

Исходный код (C++)
Unigine::Vector<Editor::PluginInfo *> plugin_infos = Editor::PluginManager::plugins();

// choose your `PluginInfo*`:
Editor::PluginInfo *required_plugin_info = ..;

// Unload a plugin:
bool unloaded = Editor::PluginManager::unloadPlugin(required_plugin_info);

// Do something
// ...

// Reload the plugin
bool loaded = Editor::PluginManager::loadPlugin(required_plugin_info);
Последнее обновление: 10.10.2022
Build: ()