While our game may be running without any issues in the editor or even in…
Plugin creation in UE4
In this post, we’re going to create a blank C++ plugin in UE4 and then export it to re-use it on another project. I like to think of plugins as a way to create reusable logic that can be added to other C++ projects fast and easy.
Creating a Plugin
Create a blank C++ project and then, navigate to Edit -> Plugins menu and click the New Plugin button on the bottom right corner. Then, select a blank plugin and name it MyAwesomePlugin just to match the post’s instructions. When Unreal has finished creating your plugin, you have to restart your editor and rebuild your project so your plugin can be included in your project. Once you have completed these steps, open your project inside visual studio and locate the MyAwesomePlugin.uplugin file inside the Plugins folder that has been created by the editor.
This file contains all the necessary information about your plugin, while some of these options can be edited through the Editor, I prefer to edit this file instead. Go ahead and perform the marked changes in your file as shown in the screenshot above. We need to mark the plugin as Installed because we would like to export it for later use in another project.
The Type field can take a number of different values, based on what we need:
- A Runtime value means that our module will exist in the shipping build
- A Developer value means that your module will be available in the editor and in the development build but not in the shipping build
Once you perform these modifications, build your project and restart the editor.
Then, go ahead and create a new C++ class that inherits the ActorComponent. Please note that while you’re on the c++ wizard you can select where your class resides to. In this case, we’re going to add this component to our plugin:
Once you create your class, your compile will fail and the following error will pop up in your output log:
1 2 3 4 5 6 7 8 |
CompilerResultsLog: Info Creating makefile for hot reloading PluginTut (.uproject file is newer) CompilerResultsLog: Info Compiling game modules for hot reload CompilerResultsLog: Info ERROR: All source files in module "MyAwesomePlugin" must include the same precompiled header first. Currently "I:\Unreal Projects\PluginTut\Plugins\MyAwesomePlugin\Source\MyAwesomePlugin\Private\MyAwesomePluginPrivatePCH.h" is included by most of the source files. The following source files are not including "I:\Unreal Projects\Plu ginTut\Plugins\MyAwesomePlugin\Source\MyAwesomePlugin\Private\MyAwesomePluginPrivatePCH.h" as their first include: CompilerResultsLog: Info CompilerResultsLog: Info I:\Unreal Projects\PluginTut\Plugins\MyAwesomePlugin\Source\MyAwesomePlugin\Private\MyPluginComponent.cpp (including I:\Unreal Projects\PluginTut\Plugins\MyAwesomePlugin\Source\MyAwesomePlugin\Public\MyAwesomePlugin.h) CompilerResultsLog: Info LogMainFrame: MainFrame: Module compiling took 1.553 seconds |
Currently, this is a normal behavior. The workaround for this is to navigate to the MyAwesomePluginPrivatePCH.h file and include the “Engine.h” file right under MyAwesomePlugin.h. Once you complete this step, open up the MyPluginComponent.cpp file and include the MyAwesomePluginPrivatePCH as its header file. To sum up, here are both files at this point:
1 2 3 4 5 6 |
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved. #include "MyAwesomePlugin.h" #include "Engine.h" // You should place include statements to your module's private header files here. You only need to // add includes for headers that are used in most of your module's source files though. |
1 2 3 |
#include "MyAwesomePluginPrivatePCH.h" #include "MyAwesomePlugin.h" #include "MyPluginComponent.h" |
When you perform these changes, your project will compile just fine. Since the purpose of this post it to understand how to create a basic plugin so we won’t create any fancy behavior for our component, just add a log inside your BeginPlay function:
1 2 3 4 5 6 |
void UMyPluginComponent::BeginPlay() { Super::BeginPlay(); GLog->Log("BeginPlay in your Awesome Plugin Component has fired!"); } |
In this case, let’s assume that the component we have added inside our Plugin is super useful and we want to add it to some actors in our game. To do that, we have to open the [OurProjectName].Build.cs file and include the plugin in the Public Dependency Modules:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "MyAwesomePlugin" });After completing this step, we can include the MyAwesomeComponent.h header file to an actor class and create the component as any other component. To demonstrate that, I have created a DummyActor and I have added our component:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include "GameFramework/Actor.h" #include "MyPluginComponent.h" #include "MyActor.generated.h" UCLASS() class PLUGINTUT_API AMyActor : public AActor { GENERATED_BODY() protected: UPROPERTY(VisibleAnywhere) UMyPluginComponent* MyPluginComponent; public: // Sets default values for this actor's properties AMyActor(); // Called when the game starts or when spawned virtual void BeginPlay() override; // Called every frame virtual void Tick( float DeltaSeconds ) override; }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include "PluginTut.h" #include "MyActor.h" // Sets default values AMyActor::AMyActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; MyPluginComponent = CreateDefaultSubobject<UMyPluginComponent>(FName("MyPluginComponent")); } // Called when the game starts or when spawned void AMyActor::BeginPlay() { Super::BeginPlay(); } // Called every frame void AMyActor::Tick( float DeltaTime ) { Super::Tick( DeltaTime ); } |
Packaging our plugin
In order to package your plugin, go to Edit -> Plugins menu and select your plugin. Then, select the Package option. The editor will build your plugin for all the supported platforms and create a folder with your packaged build. To use your plugin in another project, copy the Plugins folder (it is located inside [YourExportFolder]->HostProject) inside your desired project. Please note that the target project has to be a C++ project.
Working in 4.18 the compilation also fails but the *PrivatePCH.h is not created it seems.
I got it working by restarting the editor and building again.
I had the same thing happen as well. In 4.19.2 there is no PrivatePCH.h file that is created.
I am sort of stuck at the end though with adding to an actor class. Too new to Unreal to understand from there on…
Got the same error in 4.2.5. Restarting the editor and rebuilding did not work for me. Fixed by following Puppet Master’s instructions to create the plugin manually. Had to create Plugins/Source/MyPlugin/Private/MyPluginPrivatePCH.h from scratch. For some reason the PrivatePCH.h file does not exist under the blank plugin template and is not created when using the new plugin wizard.