Хочешь уверенно проходить IT-интервью?
![Готовься к IT-собеседованиям уверенно с AI-тренажёром T1!](https://media.proglib.io/banner/2025/01/28/t1.jpg)
Мы понимаем, как сложно подготовиться: стресс, алгоритмы, вопросы, от которых голова идёт кругом. Но с AI тренажёром всё гораздо проще.
💡 Почему Т1 тренажёр — это мастхэв?
- Получишь настоящую обратную связь: где затык, что подтянуть и как стать лучше
- Научишься не только решать задачи, но и объяснять своё решение так, чтобы интервьюер сказал: "Вау!".
- Освоишь все этапы собеседования, от вопросов по алгоритмам до диалога о твоих целях.
Зачем листать миллион туториалов? Просто зайди в Т1 тренажёр, потренируйся и уверенно удиви интервьюеров. Мы не обещаем лёгкой прогулки, но обещаем, что будешь готов!
Реклама. ООО «Смарт Гико», ИНН 7743264341. Erid 2VtzqwP8vqy
Также предполагается, что читатель базово знаком с C++ и блюпринтами, в частности, с библиотеками BP-функций [1].
Как связаны между собой плагины и модули
Плагины [2] могут состоять из одного или нескольких модулей, а могут не иметь модулей вообще. Плагин более высокоуровневая структура, нежели модуль. В отличие от модулей, плагины могут содержать контент. Плагины можно продавать в Epic Marketplace, модули – нет.
Плагины могут зависеть от плагинов, а модули – от модулей. Обратите внимание, что когда мы говорим про зависимости между плагинами, существует некая иерархия, определяющая допустимые варианты зависимостей.
Существует два типа плагинов: игровые и плагины движка. Последние содержат функциональность, которая может быть использована в разных проектах, а игровые плагины специфичны для конкретного проекта. Из-за этого они могут зависеть от плагинов движка, в то время как обратная зависимость недопустима. При этом в своей функциональности игровые плагины и плагины движка абсолютно идентичны: всё, что могут одни, могут и другие.
Создаём основу плагина
Всё, что будет описано в этом разделе, можно выполнить, используя интерфейс редактора движка. Для лучшего понимания устройства вещей мы сделаем всё вручную, однако в конце раздела кратко опишем и более простой вариант.
Предположим, что у вас уже есть проект* на C++ и ваша IDE открыта. Предположим также, что вы решили разработать игровой плагин, а не плагин движка. Заметьте, что в статье мы будем использовать UE 4.27.0 без исходного кода.
Перейдем в директорию, где находится проект. Теперь в папке Plugins
создадим директорию для нашего плагина, который будет называться SupremePlugin
. Директория должна быть одноимённой.
Создадим следующие файлы и поддиректории:
![Содержимое директории нашего плагина.](https://media.proglib.io/posts/2021/09/17/d8a358c205793dc25bbc4837415d5474.png)
Много всего, правда? Расскажем обо всём по порядку:
SupremePlugin.uplugin
[3] – дескриптор плагина, который должен иметь имя <PluginName>Plugin.uplugin
. В нашем случае его содержимое таково:
{
"FileVersion" : 3,
"Version" : 1,
"VersionName" : "1.0",
"FriendlyName" : "Supreme Plugin",
"Description" : "A dumb plugin",
"Category" : "Other",
"CreatedBy" : "Proglib",
"CreatedByURL" : "https://proglib.io",
"DocsURL" : "",
"MarketplaceURL" : "",
"SupportURL" : "",
"EnabledByDefault" : true,
"CanContainContent" : false,
"Installed" : false,
"Modules" :
[
{
"Name" : "SupremePlugin",
"Type" : "Runtime",
"LoadingPhase" : "Default"
}
]
}
Большинство полей говорят сами за себя, но мы разберём несколько самых важных:
EnabledByDefault
– должен ли плагин быть включен сразу после установки.CanContainContent
– определяет, может ли плагин содержать ассеты.Installed
– определяет, был ли плагин установлен поверх или является частью движка/проекта:
![Влияние <code class="inline-code">Installed</code> на отображение плагина в редакторе.](https://media.proglib.io/posts/2021/09/17/1f0c9791390d02a84944a2ebf05a468c.png)
Installed
на отображение плагина в редакторе.Modules
– одно из самых важных полей – список модулей плагина. Здесь мы указываем единственный модуль нашего плагина.
Файл SupremePlugin.Build.cs
описывает единственный модуль плагина – SupremePlugin
. Мы не будем подробно останавливаться на его синтаксисе (т.к. разбирали его в статье про модули), а лишь приведём его содержимое:
namespace UnrealBuildTool.Rules
{
public class SupremePlugin : ModuleRules
{
public SupremePlugin(ReadOnlyTargetRules Target) : base(Target)
{
PublicDependencyModuleNames.AddRange(
new string[] //Зависимости нашего модуля
{
"Core",
"CoreUObject",
"Engine",
“DeveloperSettings”
}
);
}
}
}
Хедер SupremePlugin.h
ничего не содержит, в то время как SupremePlugin.cpp
содержит определение нашего модуля (подробнее об этом мы также говорили в статье про модули):
#include "SupremePlugin.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_MODULE(FDefaultModuleImpl, SupremePlugin)
Наконец, пара .h
/.cpp
-файлов SupremeNativeFunctionLibrary
задаёт “полезную нагрузку” нашего плагина – библиотеку BP-функций SupremeNativeFunctionLibrary
, с единственной функцией DoSomethingUseful()
, которая, по легенде, делает что-то полезное.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "SupremeNativeFunctionLibrary.generated.h"
UCLASS()
class SUPREMEPLUGIN_API USupremeNativeFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, meta=(Category="Supreme Functionality"))
static void DoSomethingUseful();
};
#include "SupremeNativeFunctionLibrary.h"
void USupremeNativeFunctionLibrary::DoSomethingUseful()
{
UE_LOG(LogTemp, Log, TEXT("Kinda useful functionality"));
}
Теперь достаточно собрать и запустить проект и в редакторе блюпринтов станет доступной функция DoSomethingUseful()
.
![Использование BP-функциональности из нашего плагина.](https://media.proglib.io/posts/2021/09/17/e2dddde640938da2909f385a4ccb72b0.png)
На данный момент в редакторе наш плагин отображается с иконкой по умолчанию:
![Отображение плагина в редакторе.](https://media.proglib.io/posts/2021/09/17/d38c1fa20b5ae900c9ef86834d9d48c5.png)
Чтобы заменить иконку, необходимо создать папку Resources в корне плагина и добавить в неё изображение с именем Icon128.png
, с разрешением 128x128.
Чтобы создать плагин, используя редактор движка, достаточно открыть панель Plugins и нажать New Plugin. Здесь вам будет предложено выбрать один из нескольких типовых шаблонов для будущего плагина, ввести имя и базовую мета-информацию:
![Мастер создания плагинов встроенный в редактор.](https://media.proglib.io/posts/2021/09/17/835cc70543b2fed5f3cd609333d88067.png)
Конфигурация плагина
Предположим, что нас не устраивает, что DoSomethingUseful()
выводит сообщение, которое нельзя изменить без изменения кода. В таком случае для плагина стоит добавить конфигурацию, через которую можно будет изменять подобные параметры.
Конфигурация в UE происходит через обычные UObject
’ы с UProperty
, помеченными с помощью спецификатора Config
. Всё, что необходимо сделать – это создать класс для конфигурации, который содержал бы необходимые поля.
В нашем случае класс будет полностью описан в хедере. Создадим хедер SupremePluginSettings.h
([4], [5], [6]):
#pragma once
#include "Engine/DeveloperSettings.h"
#include "SupremePluginSettings.generated.h"
//Здесь Config указывает имя файла, в котором будет храниться конфигурация
//DefaultConfig говорит движку перезаписывать Default*.ini-файлы [4], а не создавать поверх них локальные файлы конфигурации
//Соответственно, конфигурация данного класса будет храниться в DefaultGame.ini
UCLASS(Config=Game, DefaultConfig, meta=(DisplayName="Supreme Plugin Settings"))
//Если бы USupremePluginSettings был унаследован напрямую от UObject [5], а не от UDeveloperSettings [6], то тогда бы он не был доступен для редактирования в Project Settings в редакторе
class SUPREMEPLUGIN_API USupremePluginSettings : public UDeveloperSettings
{
GENERATED_BODY()
public:
UPROPERTY(Config, EditAnywhere, Category = "Main")
FString Message; //Свойство, которое будет содержать необходимое сообщение
};
Теперь значение Message
можно редактировать через Project Settings в редакторе:
![Конфигурирование плагина через настройки проекта](https://media.proglib.io/posts/2021/09/17/a4fc111755e68460b8ccfeac3cee77dd.png)
Остаётся лишь каким-либо образом получить значение поля Message
в нашей DoSomethingUseful()
. Это можно сделать, используя систему CDO (Class Default Object). Её подробное рассмотрение выходит за рамки статьи, но вот ссылка на документацию для интересующихся.
Обновим SupremeNativeFunctionLibrary.cpp
:
#include "SupremeNativeFunctionLibrary.h"
#include "SupremePluginSettings.h"
void USupremeNativeFunctionLibrary::DoSomethingUseful()
{
FString Message = GetDefault<USupremePluginSettings>()->Message; //Получение значения Message через CDO USupremePluginSettings
UE_LOG(LogTemp, Log, TEXT("%s"), *Message);
}
Отключение плагина без открытия проекта
В случае, если ваш плагин падает и не даёт открыть редактор, а значит не позволяет отключить самого себя, существует способ отключить плагин без использования GUI. Для этого откройте .uproject
и в разделе Plugins
добавьте запись с необходимым плагином и полем Enabled
, установленным в false
:
...
"Plugins" : [
{
"Name": "SupremePlugin",
"Enabled": false
}
],
...
Вывод
Плагины в UE могут содержать несколько модулей, а могут не содержать модулей вообще. В отличие от модулей, плагины могут нести с собой ассеты и распространяться на Epic Marketplace. Плагин более высокоуровневая единица абстракции, нежели модуль.
На Unreal Engine сделаны многие современные игры, поэтому движок однозначно рекомендован к изучению всем интересующимся геймдевом. На самостоятельное освоение всех его возможностей потребуются не один год, но есть и более короткий путь. Обратите внимание на курс факультета разработки игр на Unreal Engine 4 образовательной онлайн-платформы GeekBrains. Вы освоите сам движок, научитесь программировать на Blueprints и C++ и сможете самостоятельно создавать игры с нуля. Занятия ведут эксперты-разработчики российских технологических компаний, а успешно окончившие курс студенты получат диплом о профессиональной переподготовке, несколько проектов в портфолио и помощь в трудоустройстве.
Источники
- https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/BlueprintFunctionLibraries/
- https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/Plugins/
- https://docs.unrealengine.com/4.27/en-US/API/Runtime/Projects/FPluginDescriptor/
- https://docs.unrealengine.com/4.27/en-US/ProductionPipelines/ConfigurationFiles/
- https://docs.unrealengine.com/4.27/en-US/API/Runtime/CoreUObject/UObject/UObject/
- https://docs.unrealengine.com/4.27/en-US/API/Runtime/DeveloperSettings/Engine/UDeveloperSettings/
- https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Objects/
Комментарии