Files
unreal-engine-mcp-system-pl…/Source/UEBlueprintMCPEditor/UEBlueprintMCPEditor.Build.cs
Bonchellon eba71c4ca8 Unified, portable Unreal Engine MCP system plugin
Merge of the two project copies into one self-contained plugin (the superset:
variable_op + variables.py, full pcg_op runtime/declarative/preset ops, the
CreateWidgetFloatAnimation widget tool, and full Voxel graph authoring).

Made fully project- and machine-agnostic — no hardcoded paths:
- New src/projectPaths.js auto-detects the host .uproject (walk-up), project
  name, Editor build target, log file, and engine install (EngineAssociation
  via launcher manifest/registry, else installed-engine scan). All overridable
  via UE_* env vars.
- Rewired buildOrchestrator/insights/launcher/insightsExporter/server.js and the
  Python workers (cpp_scaffold, live_coding, apply_graph, console) off the old
  C:/Github/ihy, IHY*, E:/UE_Versions and UE_5.7 literals onto the resolver.
- Voxel made optional: Build.cs auto-detects the Voxel plugin (env
  UE_MCP_WITH_VOXEL override) and the C++ compiles to stubs under WITH_MCP_VOXEL,
  so the module builds in projects without Voxel; .uplugin marks Voxel optional.
- De-branded the agent-gateway and docs; scrubbed a leaked API key; excluded
  node_modules/Binaries/Intermediate/__pycache__/secrets from the repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 01:07:24 +03:00

130 lines
4.6 KiB
C#

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",
"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 <Voxel>/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<string>();
if (Target.ProjectFile != null)
{
roots.Add(Path.Combine(Target.ProjectFile.Directory.FullName, "Plugins"));
}
// The Plugins folder this plugin itself lives in (covers <Project>/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;
}
}