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>
130 lines
4.6 KiB
C#
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;
|
|
}
|
|
}
|