using System; using System.IO; using System.Collections.Generic; using UnrealBuildTool; public class UEBlueprintMCPEditor : ModuleRules { public UEBlueprintMCPEditor(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "UMG", }); PrivateDependencyModuleNames.AddRange(new string[] { "UnrealEd", "UMGEditor", "BlueprintGraph", "KismetCompiler", "Kismet", "GraphEditor", "InputCore", "Slate", "SlateCore", "EditorSubsystem", "ToolMenus", "AssetTools", "Projects", "Json", "JsonUtilities", "AssetRegistry", "HTTP", "Niagara", "NiagaraCore", "NiagaraEditor", "ImageWrapper", "RenderCore", "RHI", "MovieScene", "MovieSceneTracks", }); // ---- Optional Voxel integration ----------------------------------- // voxel_graph_op needs Voxel's editor modules. Voxel is a heavy third-party // plugin most projects don't have, so it is wired in ONLY when present. The // C++ side guards everything behind WITH_MCP_VOXEL and compiles to stubs at 0. // env UE_MCP_WITH_VOXEL = "1" -> force on (errors if the plugin is missing) // env UE_MCP_WITH_VOXEL = "0" -> force off // unset -> auto-detect string voxelEnv = Environment.GetEnvironmentVariable("UE_MCP_WITH_VOXEL"); string voxelPrivate = (voxelEnv == "0") ? null : FindVoxelGraphEditorPrivate(Target); bool voxelEnabled = voxelPrivate != null && voxelEnv != "0"; if (voxelEnabled) { // Reach a few VoxelGraphEditor private headers (node classes). We only use // inline/virtual members, so no private link symbols cross the boundary. PrivateIncludePaths.Add(voxelPrivate); PrivateDependencyModuleNames.AddRange(new string[] { "VoxelCore", "VoxelCoreEditor", "VoxelGraph", "VoxelGraphEditor", }); PublicDefinitions.Add("WITH_MCP_VOXEL=1"); } else { if (voxelEnv == "1") { throw new BuildException( "UE_MCP_WITH_VOXEL=1 but the Voxel plugin (Source/VoxelGraphEditor/Private) " + "could not be located. Install the Voxel plugin into this project or the engine, " + "or unset UE_MCP_WITH_VOXEL."); } PublicDefinitions.Add("WITH_MCP_VOXEL=0"); } } // Locate /Source/VoxelGraphEditor/Private by scanning the project's and // engine's plugin folders for Voxel.uplugin. Returns null if Voxel isn't installed. private string FindVoxelGraphEditorPrivate(ReadOnlyTargetRules Target) { var roots = new List(); if (Target.ProjectFile != null) { roots.Add(Path.Combine(Target.ProjectFile.Directory.FullName, "Plugins")); } // The Plugins folder this plugin itself lives in (covers /Plugins/Voxel). roots.Add(Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "..", ".."))); try { roots.Add(Path.Combine(EngineDirectory, "Plugins")); } catch { } foreach (string root in roots) { string hit = FindVoxelUnder(root, 0); if (hit != null) return hit; } return null; } // Bounded, fault-tolerant recursive search (GetFiles+AllDirectories aborts wholesale // on a single inaccessible subdir, so we walk manually and swallow per-dir errors). private string FindVoxelUnder(string dir, int depth) { if (depth > 5 || string.IsNullOrEmpty(dir) || !Directory.Exists(dir)) return null; try { string upl = Path.Combine(dir, "Voxel.uplugin"); if (File.Exists(upl)) { string priv = Path.Combine(dir, "Source", "VoxelGraphEditor", "Private"); if (Directory.Exists(priv)) return priv; } foreach (string sub in Directory.GetDirectories(dir)) { string hit = FindVoxelUnder(sub, depth + 1); if (hit != null) return hit; } } catch { } return null; } }