Tutorial: Unreal Engine C++ Plugin
Why a plugin?
Plugins are a great way to structured your code and make it reusable. This way you can unclutter your codebase and keep everything neatly organized. You can also share your plugin via the Unreal Marketplace.
Prerequisites
For this tutorial, I assume, that you have a working Unreal Engine C++ project already setup.
The easy way using Rider
If you are using a recent version of Rider (I am using 2012.2), you can simply use the context menu that appears, when you right click on the plugin folder in your solution explorer. If you don’t have a plugin folder, you can create one.
Rider Context Menu
After you click on Unreal Plugin…, another dialog opens where you can select multiple settings. This is mostly identical to the Unreal Engine Editor plugin wizard. For more information on the single settings, keep reading.
The Unreal Editor way
In the editor, click on the top-right settings button (the one with the gear icon) and select the Plugins option. The plugin editor window should now open. In the top left corner, you will find an Add button. Press that, and the plugin creation wizard appears.
Editor Plugin Window
Creating the plugin
There are multiple templates from which you can choose. Most of the templates include some kind of exemplary code for a certain feature. Most of them are related to specific editor functionality. You can of course, always add the corresponding code to a blank plugin and get the sam functionality. If you are not sure, what kind of plugin you need choose the blank template and adjust it to your needs later.
Tip
While you can change pretty much everything about a plugin, even after its creation, it is really annoying to change the name afterward. So, make sure you choose a good name right away.
And that’s it! You can now start creating classes in the source directory of your plugin, just as you would in your parent project.
If you use the Unreal Class Wizard to create your c++ classes, you can now select your plugin as the containing module for your code.
Class Wizard and the module selection
Anatomy of a plugin
After creating your plugin you will have a new folder in your project directory called Plugins.
├── Content
├── Plugins
│ ├── MyPlugin
│ │ ├── Content
│ │ ├── Intermediate
│ │ ├── Resources
│ │ ├── Source
│ │ ├── MyPlugin.uplugin
├── Source
A plugin directory is similar to the project directory. It contains a content directory for all the binary assets, like Blueprints, Textures, Materials, etc. It also contains a source directory where all the source code is in. It has the same structure as the Source directory of your project. The resources directory contains an icon (png). It’s displayed in the editor’s plugin window. You can ignore the intermediate directory. It is only for the IDE and the Engine. The .uplugin file is similar to the .uproject file of your main project.
Let’s take a closer look the .uplugin file:
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "MyPlugin",
"Description": "This is my first plugin.",
"Category": "Other",
"CreatedBy": "Kevin",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "MyPlugin",
"Type": "Runtime",
"LoadingPhase": "Default"
}
]
}
Most of these are self explanatory so let’s focus on the Modules entry for now. By default a plugin contains one module. That is the entry in the modules array you can see above. More information about modules can be found here. The module is referenced by name. Rider offers auto completion for module names, but if you don’t have Rider make sure your spelling is correct, when referencing other modules.
For plugins, that provide runtime functionality the Runtime type is the correct type. It means that your module will always be available at runtime. Another popular choice is the Editor type. This type is used, when the module should only be present when the editor is running. In builds that run without the editor the module will not be available. This can lead to build errors, when you try to link against a module that is not available without the editor. You can find the documentation for all the types here.
If you are not sure which loading phase is the right for you, leave it at Default. If your module depends on another module, you might have to load it after that and an other loading phase might be a better choice. The documentation for the loading phases can be found here.
A plugin can also depend on other plugins. You need to add a Plugins array to the .uplugin file to add a dependency. I am going to add the CommonUI plugin as an example.
{
"Modules": [
{
"Name": "MyPlugin",
"Type": "Runtime",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "CommonUI",
"Enabled": true
}
]
}
Now, the plugin and its content can be used inside Blueprints and the editor. However, if you want to use classes from the CommonUI plugin in your code, you need to reference the plugin in the corresponding MyPlugin.Build.cs file.
PrivateDependencyModuleNames.AddRange(
new string[] {
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"CommonUI", // <=== add this!
}
);
Caution
If you forget the step above, you will receive a lot of linker errors.
Now, we can access all the classes and functions from the CommonUI plugin inside our own plugin. The same is true for our plugin and our parent project we are using the plugin in.
Unreal does not automatically add the plugin to the build or the uproject file (Rider has a checkbox for this!).
So, we have to do that ourselves.
Add the plugin to our Tutorials.Build.cs file:
public class Tutorials : ModuleRules
{
public Tutorials(ReadOnlyTargetRules Target) : base(Target)
{
PrivateDependencyModuleNames.AddRange(new string[] { "MyPlugin" });
}
}
And add the plugin to our Tutorials.uproject file:
{
"FileVersion": 3,
"EngineAssociation": "5.4",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "Tutorials",
"Type": "Runtime",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "MyPlugin",
"Enabled": true
}
]
}
To Sum it up
A plugin is essentially a container for modules, and it can contain as many modules as you need. Unlike a project, a plugin can be easily shared across different projects, making it an excellent tool for code or assets that can be reused. Adopting a module/plugin-based approach can save you significant time in the long run, as you won’t need to reinvent the wheel every time you require basic functionality. The key to this modular and decoupled approach is a well-designed architecture that minimizes coupling and tight dependencies. When used correctly, this can be a very powerful tool.
I hope you found this tutorial useful. For the full source code, you can visit the repo on GitHub.