
Plugin and module system in Unreal Engine 4
- Tutorial

Hello, my name is Dmitry. I make computer games on the Unreal Engine as a hobby. Today I will tell you how to create your own module, and then how to create a plugin in Unreal Engine 4.
Creating a module
So, let's start with the modules. When you create a project, one module is automatically created in the project file.
{
"FileVersion": 3,
"EngineAssociation": "4.10",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "UICustom",
"Type": "Runtime",
"LoadingPhase": "Default"
}
]
}
In principle, for a simple project this is enough. But if you read my previous article (and if you didn’t read it, I advise you to do it right now) you can see that we don’t need a certain code that is needed to register an asset, add buttons to the properties panel of this asset, but only for the editor. Therefore, it would be good to make it so that during the assembly of the game this code would not be included in the game, this is exactly what the module system is for.
So, let's begin. First, add another module:
{
"FileVersion": 3,
"EngineAssociation": "4.10",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "UICustom",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "UICustomEditor",
"Type": "Editor",
"LoadingPhase": "Default"
}
]
}
Module parameters
The module has a type parameter that determines where the module should be included and where not. The type can take the following values:
The module also has a LoadingPhase parameter that defines the stage of loading the module:
namespace EHostType
{
enum Type
{
Runtime,
RuntimeNoCommandlet,
Developer,
Editor,
EditorNoCommandlet,
Program,
Max,
}
}
The module also has a LoadingPhase parameter that defines the stage of loading the module:
namespace ELoadingPhase
{
enum Type
{
Default,
PostDefault,
PreDefault,
PostConfigInit,
PreLoadingScreen,
PostEngineInit,
Max,
}
}
Any module must have 3 files. The first is the header file of this module <Module Name> .h, usually the Engine.h file is included in it. But it is worth noting that when you include the Engine.h file, the size of the Precompiled header becomes ~ 700mgb. If you create a lot of modules in your project, and each one weighs more than 700mgb, there won't be enough hard drives, so I recommend opening Engine.h and choosing only what you need. In addition, the module interface is located in this file. In which you can register something, for example.
#pragma once
#include "Core.h"
#include "CoreUObject.h"
#include "Engine/EngineTypes.h"
#include "SlateCore.h"
#include "SlateBasics.h"
#include "ModuleManager.h"
DECLARE_LOG_CATEGORY_EXTERN(UICustomEditor, All, All)
class FUICustomEditorModule : public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
The second required file is the file <Module Name> .cpp:
#include "UICustomEditor.h"
#include "MyObjectAssetAction.h"
#include "MyStructCustomization.h"
DEFINE_LOG_CATEGORY(UICustomEditor)
void FUICustomEditorModule::StartupModule()
{
FMyObjectAssetAction::RegistrateCustomPartAssetType();
FMyClassDetails::RegestrateCostumization();
UE_LOG(UICustomEditor, Warning, TEXT("Editor module Started"));
}
void FUICustomEditorModule::ShutdownModule()
{
UE_LOG(UICustomEditor, Warning, TEXT("Editor module Stoped"));
}
IMPLEMENT_GAME_MODULE(FUICustomEditorModule, UICustom);
Here I register the type of asset and change the properties panel, and also added a message to the log.
There must be an IMPLEMENT_GAME_MODULE macro at the end of this file.
The third required file <Module Name> .Build.cs:
using UnrealBuildTool;
public class UICustomEditor : ModuleRules
{
public UICustomEditor(TargetInfo Target)
{
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"InputCore"
});
PrivateDependencyModuleNames.AddRange(new string[] {
"Slate",
"SlateCore",
"PropertyEditor",
"UnrealEd",
"EditorStyle" });
PrivateDependencyModuleNames.AddRange(new string[] { "GameLibPluginRuntime","UICustom" }); //Плагин и основной модуль
}
}
In this file I connect the modules necessary for the operation of my module (sorry for the tautology). As you can see, in addition to system modules, I also connected the main module and the plugin (which I will write about below).
Important: If you connect the plug-in to the main module, then you must connect it to the rest. Otherwise, if you use an object from the main module in which there will be an object from the plug-in, then the compiler, giving an error that it cannot find the file, will refer to the line in the main module, but since you already connected the plug-in in it, you will not understand what is the matter and what does the compiler require of you.
Important: In order for the class or structure from the connected module to be used. Need:
1) Connect the header file of this class or structure.
2) When defining the classes and structures that you want to use from other modules, you need to write <module name in capital letters> _API. For example:
class UICUSTOMEDITOR_API UMyObjectFactory : public UFactory
After creating these files, you need to put them in the folder with the module name in the Source folder. It remains only to add our module to the UICustomEditor.Target.cs file (we do not add anything to the UICustom.Target.cs file, since the module will be loaded only in the editor)
OutExtraModuleNames.AddRange( new string[] { "UICustom", "UICustomEditor" } );
The module is ready, for the payload I used files from the last lesson. Now let's move on to creating the plugin.
Creating a Plugin
A plugin should be understood as a project that can be inserted into another project. The plugin, like the project, consists of modules and has its own project file, which has the extension .uplugin. In order to connect the plug-in to the project, you need to put it in the <project directory> / plugins folder and regenerate the Visual Studio project. After that, you can connect the plug-in modules, like any other modules (described above).
Accordingly, to create a plugin, you need to create a file <Plugin Name> .uplugin
{
"FileVersion" : 3,
"FriendlyName" : "GameLibPlugin",
"Version" : 48,
"VersionName" : "1.0",
"CreatedBy" : "Deema 35",
"CreatedByURL" : " ",
"EngineVersion" : "4.10.0",
"Description" : "Library some system structure",
"Category" : "System library",
"EnabledByDefault" : true,
"MarketplaceURL" : " ",
"Modules" :
[
{
"Name" : "GameLibPluginRuntime",
"Type" : "Runtime",
"LoadingPhase" : "PreDefault"
},
{
"Name" : "GameLibPluginEditor",
"Type" : "Editor"
}
],
"CanContainContent" : true
}
If you create the Resources folder in the plug-in folder, then the image put there, in png format, will be displayed in the plug-in manager.
Next, in <plugin folder> / Source, create a folder for each of the plugin modules. Creating modules for a plugin is no different from creating modules for a project (as described above). Actually, everything, the plugin is ready.
For example, I made a parser for CVS tables. After connecting the plugin, you can observe:


Project with source code: here
PS Please note that I am an amateur programmer, so please do not kick the parser.