【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」として定義
Information

ここで使用した「OculusXR」というプラグイン名は *.uproject などに書かれているものを使います。

Meta XR Pluginであれば、例えば以下のような定義名が見つかります。

		{
			"Name": "OculusXR",
			"Enabled": false,
			"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/8313d8d7e7cf4e03a33e79eb757bccba",
			"SupportedTargetPlatforms": [
				"Win64",
				"Android"
			]
		}

これにより、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 が生成されるようです。

参考

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

\ 最新情報をチェック /