I am developing custom plugins for our project and want to have ability to check if plugin is loaded and build. Some define directive which would be imported if my project uses this plugin.
Is it possible to do with unreal build system?
I am developing custom plugins for our project and want to have ability to check if plugin is loaded and build. Some define directive which would be imported if my project uses this plugin.
Is it possible to do with unreal build system?
I’m currently looking for the same thing. Can you share you solution (if any) ?
I finally found that you just need to use FModuleManager::Get().IsModuleLoaded("YourModuleName")
to check whether or not your plugin is loaded
I’m not sure if adding some C++ code into your plugin is mandatory or not though. I followed this tutorial here, at the section Stand Alone Plugin
Good luck.
Best regards.
I don’t remember what I need it for ) But IsModuleLoaded solution is not appropriate if you need to switch off some include directives.
But I somehow abandoned that idea and found other solution.
Still having a PLUGIN_ENABLED directive can allow to make some interesting trick with the project.
Also interesting question is how to check if plugin is enabled in Build Scripts.
I agree on that macro trick that would be great. I was mostly looking for “ability to check if plugin is loaded and build” during runtime and I didn’t find anything except your topic here so yeah, I guess it’s fine to put any kind of information related to this topic here anyway
Did you ever find a solution for this? I’ve got the same problem, I’d like to check that my module is loaded so that I can safely include a file from it…
I was able to achieve this. The following code is from the build.cs file of the main module of my plugin, but should work normally on the project’s build.cs file too.
`public class StreamlinePlatform : ModuleRules
{
public StreamlinePlatform(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"DeveloperSettings",
"Engine",
"OnlineSubsystem",
"OnlineSubsystemUtils",
}
);
UnsafeTypeCastWarningLevel = WarningLevel.Error;
StreamlinePlatform.ConfigurePlugins(this, Target);
}
static public void ConfigurePlugins(ModuleRules Rules, ReadOnlyTargetRules Target)
{
if (Target.bUsesSteam == true)
{
Rules.PublicDefinitions.Add("WITH_STEAM=1");
}
JsonObject RawObject;
if (JsonObject.TryRead(Target.ProjectFile, out RawObject))
{
JsonObject[] pluginObjects;
if (RawObject.TryGetObjectArrayField("Plugins", out pluginObjects))
{
foreach (JsonObject pluginObject in pluginObjects)
{
string pluginName;
pluginObject.TryGetStringField("Name", out pluginName);
bool pluginEnabled;
pluginObject.TryGetBoolField("Enabled", out pluginEnabled);
if (pluginName == "OnlineSubsystemSteam" && pluginEnabled)
{
if (Target.bUsesSteam == false)
{
Rules.PublicDefinitions.Add("WITH_STEAM=1");
}
}
}
}
}
}
}`
Where does the JsonObject come from? Im getting missing namespace errors with this code from that.
using UnrealBuildTool;
This put me on the right path but JsonObject
is in EpicGames.Core
not UnrealBuildTool
.
This is how my plugin successfully checks if they have GameplayAbilities plugin enabled, tested and working.
Tested it (only on windows):
I do not know if it works when you enable/disable the GameplayAbilities plugin in some unrelated .uplugin instead of your .uproject
Rider correctly detects this also. But when enabling/disabling the plugin to get it to update you have to restart Rider. If you right click your plugin module and “Reload Project” it detects the state of the pre-processor macro but thinks you’re missing includes.
Honestly, I don’t like it. Unreal needs to provide “official” tools to deal with this.
I haven’t tried it but I can’t see why it wouldn’t work - maybe an easy way to find if a plugin is installed is to do a “FileManager->DirectoryExists” for the plugin folder?
No - that will always be true for the editor because the directory will exist regardless. I included the solution in that Build.cs link.
Do you know if there’s a way to conditionally include .cpp and .h files in the build dependant on the results from the json find?
Edit: just noticed you mention unreal build system Ok the following code works with projects though, I’ll leave it up here just in case someone need the code in the future.
Example project ue 5.4
PluginTestProj.zip (78.0 KB)
Static lib to test if plugin is loaded and enabled:
header file
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "PluginTester.generated.h"
/**
*
*/
UCLASS()
class YOUR_API UPluginTester : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static bool TestPluginLoaded(FString pluginName);
};
cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PluginTester.h"
#include "Interfaces/IPluginManager.h"
bool UPluginTester::TestPluginLoaded(FString pluginName) {
TSharedPtr<IPlugin> plug = IPluginManager::Get().FindEnabledPlugin(pluginName);
if (plug != nullptr) {
if (plug.Get() != nullptr) {
return true;
}
}
return false;
}
Needed Modules in build file:
"Projects"
example:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "Projects" });
Tested in shipping version and it worked.
Just want to add even though i didnt find the solution from this thread i ended up stumbling on the IPluginManager and that helped me achieve the exact same functionality so this does in fact work.
Yes - did you read the files I linked? The answer is there. Click “Actual Usage” link.
I feel like maybe people aren’t able to read the links or are missing them, so here is the full solution:
PhysicsHitReact.Build.cs
using UnrealBuildTool;
using EpicGames.Core; // IMPORTANT - CONTAINS JsonObject
public class PhysicsHitReact : ModuleRules
{
public PhysicsHitReact(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"GameplayTags",
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"PhysicsCore",
}
);
// Add pre-processor macros for the GameplayAbilities plugin based on enabled state (optional plugin)
PublicDefinitions.Add("WITH_GAMEPLAY_ABILITIES=0");
if (JsonObject.TryRead(Target.ProjectFile, out var rawObject))
{
if (rawObject.TryGetObjectArrayField("Plugins", out var pluginObjects))
{
foreach (JsonObject pluginObject in pluginObjects)
{
pluginObject.TryGetStringField("Name", out var pluginName);
pluginObject.TryGetBoolField("Enabled", out var pluginEnabled);
if (pluginName == "GameplayAbilities" && pluginEnabled)
{
PrivateDependencyModuleNames.Add("GameplayAbilities");
PublicDefinitions.Add("WITH_GAMEPLAY_ABILITIES=1");
PublicDefinitions.Remove("WITH_GAMEPLAY_ABILITIES=0");
}
}
}
}
}
}
PhysicsHitReact.uplugin - Note the "Optional": true
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.1.0",
"FriendlyName": "PhysicsHitReact",
"Description": "Procedural physics-driven hit reactions on skeletal meshes",
"Category": "Animation",
"CreatedBy": "Jared Taylor (Vaei)",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"CanContainContent": false,
"IsBetaVersion": true,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "PhysicsHitReact",
"Type": "Runtime",
"LoadingPhase": "PreDefault"
}
],
"Plugins": [
{
"Name": "GameplayAbilities",
"Enabled": false,
"Optional": true
}
]
}
Usage - Includes
#if WITH_GAMEPLAY_ABILITIES
#include "AbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#endif
Usage - Function
#if WITH_GAMEPLAY_ABILITIES
AbilitySystemComponent = AbilitySystemComponent.IsValid() ? AbilitySystemComponent.Get() : UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(GetOwner());
if (AbilitySystemComponent.IsValid())
{
// Do something
}
#endif
That doesn’t give you preprocessor macros to exclude includes & code from compiling though; the solution needs to be something available to Build.cs
I have UClasses defined in the .h files - they can’t be #ifdef’ed like that, the only solution I can think of is to actually remove the .h/.cpp files from the build if the plugin isn’t enabled - unless I’ve completely missed something?
I’m having trouble understanding what you mean with most of your responses so I’m assuming you’re talking about subclassing something from an optional plugin. That will never be possible.
My use-case is exactly what optional plugins are intended for – conditional additional functionality.
thank you.