【UE5】特定のプラグインが有効のときに定数を定義する方法
プログラマーの尾関です。
今回は、UE5で使用するプラグインが有効であるかどうかを判定して「定数を定義する」方法について紹介したいと思います。
要件定義

例えば「Meta XR」プラグインが有効かどうかを判定して、有効であればそれに付随する定数を定義、そうでなければ無効を示す定数を定義するようにします。
Build.cs で判定する
判定は Build.cs で行います。(※必要な部分を抜粋)
using UnrealBuildTool;
using EpicGames.Core; // JSONパーサーを使用するために必要
using Microsoft.Extensions.Logging; // ログのために必要.
/// <summary>
/// MyTestビルド設定スクリプト.
/// </summary>
public class MyTest: ModuleRules
{
/// <summary>
/// コンストラクタ.
/// </summary>
/// <param name="Target"></param>
public MyTest(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
// 設定ファイルを調べる.
Configure(Target);
// モジュールの有効化.
PublicDependencyModuleNames.AddRange(new string[] {
"Core"
, "CoreUObject"
, "Engine"
, "InputCore"
});
if(OculusXREnabled)
{
// OculusXRを有効化する.
//PublicDependencyModuleNames.Add("MRUtilityKit");
// プラグインが有効な場合、定数を定義
PublicDefinitions.Add("OCULUS_XR_ENABLED=1");
}
else
{
// OculusXRを無効化する.
PublicDefinitions.Add("OCULUS_XR_ENABLED=0");
}
...
}
/// <summary>
/// 設定ファイルを調べる.
/// </summary>
/// <param name="Target"></param>
private void Configure(ReadOnlyTargetRules Target)
{
// 設定ファイルのJSONをパースする.
JsonObject RootObject;
if(!JsonObject.TryRead(Target.ProjectFile, out RootObject))
{
// ファイルが見つからない場合のエラーメッセージ
Logger.LogError("設定ファイルが見つかりません: {0}", Target.ProjectFile);
return; // ファイルが見つからない.
}
// プラグイン設定の読み取り.
JsonObject[] PluginObjects;
if (!RootObject.TryGetObjectArrayField("Plugins", out PluginObjects))
{
Logger.LogError("プラグイン設定が見つかりません: {0}", Target.ProjectFile);
return; // プラグイン設定が見つからない.
}
foreach(JsonObject PluginObject in PluginObjects)
{
// プラグイン名を取得する.
string PluginName;
if (!PluginObject.TryGetStringField("Name", out PluginName))
{
Logger.LogInformation("プラグイン名が見つかりません: {0}", PluginObject);
continue; // プラグイン名が見つからない.
}
// プラグインが有効かどうかを取得する.
bool PluginEnabled;
if (!PluginObject.TryGetBoolField("Enabled", out PluginEnabled))
{
Logger.LogInformation("プラグインが無効です: {0}", PluginName);
continue; // プラグインが無効.
}
if(PluginEnabled == false)
{
Logger.LogInformation("プラグインは無効です: {0}", PluginName);
continue; // プラグインが無効.
}
// プラグインごとの設定を読み取る.
switch (PluginName)
{
case "OculusXR":
Logger.LogInformation("OculusXRを有効化します");
OculusXREnabled = true;
break;
default:
break;
}
}
}
/// <summary>
/// OculusXRを有効化するかどうか.
/// </summary>
private bool OculusXREnabled = false;
上記コードの説明としては、以下のとおりです。
- Configure() で 設定ファイルである JSON をパースして有効化されているプラグインを取得。その名前が「OculusXR」であれば 有効化フラグ "OculusXREnabled" を立てる
- "OculusXREnabled" が有効であれば、定数 "OCULUS_XR_ENABLED" を 値「1」として定義。無効の場合は値を「0」として定義
これにより、C++側で#if でコンパイル分岐を入れることが可能となります。
#if OCULUS_XR_ENABLED == 1 // "OculusXR" が有効であれば以下の定義が有効となる.
UE_LOG(LogTemp,Log,TEXT("Oculus XR Enabled"));
#endif
注意点:定数の更新方法
PublicDefinitions.Add() で追加した定数ですが、プロジェクトの再ビルドだけでは更新されません。
*.uproject から「Generate Visual Studio project files」でソリューションファイルを再生成するタイミングで Definitions.[プロジェクト名].h が生成されるようです。

参考
この記事を書くにあたって、以下の記事を参考にさせていただきました。ありがとうございます。