ue-mcp 0.4.6 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -20,13 +20,15 @@ npx ue-mcp init
|
|
|
20
20
|
|
|
21
21
|
The interactive setup will:
|
|
22
22
|
|
|
23
|
-
1.
|
|
23
|
+
1. Find your `.uproject` (auto-detects in current directory)
|
|
24
24
|
2. Let you choose which tool categories to enable
|
|
25
25
|
3. Deploy the C++ bridge plugin to your project
|
|
26
26
|
4. Enable required UE plugins (Niagara, PCG, GAS, etc.)
|
|
27
27
|
5. Detect and configure your MCP client (Claude Code, Claude Desktop, Cursor)
|
|
28
28
|
|
|
29
|
-
Restart the editor once after setup to load the bridge plugin.
|
|
29
|
+
Restart the editor once after setup to load the bridge plugin. To update later: `npx ue-mcp update`
|
|
30
|
+
|
|
31
|
+
Then ask your AI:
|
|
30
32
|
|
|
31
33
|
```
|
|
32
34
|
project(action="get_status") — verify connection
|
package/dist/tools/blueprint.js
CHANGED
|
@@ -36,7 +36,7 @@ export const blueprintTool = categoryTool("blueprint", "Blueprint reading, autho
|
|
|
36
36
|
- rename_function: Rename function. Params: assetPath, oldName, newName
|
|
37
37
|
- add_node: Add graph node (K2, AnimGraph, etc — any UEdGraphNode subclass). Params: assetPath, graphName?, nodeClass, nodeParams?
|
|
38
38
|
- delete_node: Delete node. Params: assetPath, graphName, nodeName
|
|
39
|
-
- set_node_property: Set node property. Params: assetPath, graphName, nodeName, propertyName, value
|
|
39
|
+
- set_node_property: Set node pin default or struct property (supports dot paths like "Node.IKBone.BoneName"). Params: assetPath, graphName, nodeName, propertyName, value
|
|
40
40
|
- connect_pins: Wire nodes. Params: sourceNode, sourcePin, targetNode, targetPin, assetPath, graphName?
|
|
41
41
|
- add_component: Add BP component. Params: assetPath, componentClass, componentName?
|
|
42
42
|
- compile: Compile Blueprint. Params: assetPath
|
package/package.json
CHANGED
|
@@ -1325,6 +1325,25 @@ TSharedPtr<FJsonValue> FAnimationHandlers::GetBoneTransforms(const TSharedPtr<FJ
|
|
|
1325
1325
|
return MakeShared<FJsonValueObject>(Result);
|
|
1326
1326
|
}
|
|
1327
1327
|
|
|
1328
|
+
// ---------------------------------------------------------------------------
|
|
1329
|
+
// Helper: Set the protected SegmentLength property on an FAnimLinkableElement
|
|
1330
|
+
// (e.g. FCompositeSection) via reflection.
|
|
1331
|
+
// ---------------------------------------------------------------------------
|
|
1332
|
+
static void SetSegmentLength(FAnimLinkableElement& Element, float NewLength)
|
|
1333
|
+
{
|
|
1334
|
+
FProperty* Prop = FAnimLinkableElement::StaticStruct()->FindPropertyByName(TEXT("SegmentLength"));
|
|
1335
|
+
if (!Prop) return;
|
|
1336
|
+
|
|
1337
|
+
if (FFloatProperty* FloatProp = CastField<FFloatProperty>(Prop))
|
|
1338
|
+
{
|
|
1339
|
+
FloatProp->SetPropertyValue_InContainer(&Element, NewLength);
|
|
1340
|
+
}
|
|
1341
|
+
else if (FDoubleProperty* DoubleProp = CastField<FDoubleProperty>(Prop))
|
|
1342
|
+
{
|
|
1343
|
+
DoubleProp->SetPropertyValue_InContainer(&Element, static_cast<double>(NewLength));
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1328
1347
|
// ---------------------------------------------------------------------------
|
|
1329
1348
|
// Helper: Set the protected SequenceLength property on a montage via reflection.
|
|
1330
1349
|
// Handles both float (UE 5.3 and earlier) and double (UE 5.4+) property types.
|
|
@@ -1436,7 +1455,7 @@ TSharedPtr<FJsonValue> FAnimationHandlers::SetMontageSequence(const TSharedPtr<F
|
|
|
1436
1455
|
// Update composite sections' segment lengths to match new duration
|
|
1437
1456
|
for (FCompositeSection& Section : Montage->CompositeSections)
|
|
1438
1457
|
{
|
|
1439
|
-
Section
|
|
1458
|
+
SetSegmentLength(Section, NewTotalLength);
|
|
1440
1459
|
}
|
|
1441
1460
|
|
|
1442
1461
|
Montage->PostEditChange();
|
|
@@ -1491,7 +1510,7 @@ TSharedPtr<FJsonValue> FAnimationHandlers::SetMontageProperties(const TSharedPtr
|
|
|
1491
1510
|
// Also update composite sections' segment lengths to match
|
|
1492
1511
|
for (FCompositeSection& Section : Montage->CompositeSections)
|
|
1493
1512
|
{
|
|
1494
|
-
Section
|
|
1513
|
+
SetSegmentLength(Section, NewLength);
|
|
1495
1514
|
}
|
|
1496
1515
|
Modified.Add(TEXT("sequenceLength"));
|
|
1497
1516
|
}
|
|
@@ -1986,7 +1986,7 @@ TSharedPtr<FJsonValue> FBlueprintHandlers::SetNodeProperty(const TSharedPtr<FJso
|
|
|
1986
1986
|
return MakeShared<FJsonValueObject>(Result);
|
|
1987
1987
|
}
|
|
1988
1988
|
|
|
1989
|
-
//
|
|
1989
|
+
// First try to find a pin with this name
|
|
1990
1990
|
UEdGraphPin* TargetPin = nullptr;
|
|
1991
1991
|
for (UEdGraphPin* Pin : TargetNode->Pins)
|
|
1992
1992
|
{
|
|
@@ -1997,29 +1997,81 @@ TSharedPtr<FJsonValue> FBlueprintHandlers::SetNodeProperty(const TSharedPtr<FJso
|
|
|
1997
1997
|
}
|
|
1998
1998
|
}
|
|
1999
1999
|
|
|
2000
|
-
|
|
2000
|
+
bool bSetViaPin = false;
|
|
2001
|
+
bool bSetViaProperty = false;
|
|
2002
|
+
|
|
2003
|
+
if (TargetPin)
|
|
2001
2004
|
{
|
|
2002
|
-
//
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
+
// Set pin default value using the graph's own schema
|
|
2006
|
+
const UEdGraphSchema* Schema = TargetGraph->GetSchema();
|
|
2007
|
+
if (Schema)
|
|
2005
2008
|
{
|
|
2006
|
-
|
|
2009
|
+
Schema->TrySetDefaultValue(*TargetPin, DefaultValue);
|
|
2010
|
+
TargetNode->PinDefaultValueChanged(TargetPin);
|
|
2011
|
+
bSetViaPin = true;
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
if (!bSetViaPin)
|
|
2016
|
+
{
|
|
2017
|
+
// No pin found — try setting as a node property via reflection.
|
|
2018
|
+
// Supports dotted paths like "Node.IKBone.BoneName" for AnimGraph inner structs.
|
|
2019
|
+
TArray<FString> PathParts;
|
|
2020
|
+
PinName.ParseIntoArray(PathParts, TEXT("."));
|
|
2021
|
+
|
|
2022
|
+
UStruct* CurrentStruct = TargetNode->GetClass();
|
|
2023
|
+
void* CurrentContainer = TargetNode;
|
|
2024
|
+
FProperty* FinalProp = nullptr;
|
|
2025
|
+
|
|
2026
|
+
for (int32 i = 0; i < PathParts.Num(); i++)
|
|
2027
|
+
{
|
|
2028
|
+
FProperty* Prop = CurrentStruct->FindPropertyByName(FName(*PathParts[i]));
|
|
2029
|
+
if (!Prop) break;
|
|
2030
|
+
|
|
2031
|
+
if (i < PathParts.Num() - 1)
|
|
2007
2032
|
{
|
|
2008
|
-
|
|
2033
|
+
// Intermediate path segment — drill into struct
|
|
2034
|
+
FStructProperty* StructProp = CastField<FStructProperty>(Prop);
|
|
2035
|
+
if (!StructProp) break;
|
|
2036
|
+
CurrentContainer = StructProp->ContainerPtrToValuePtr<void>(CurrentContainer);
|
|
2037
|
+
CurrentStruct = StructProp->Struct;
|
|
2038
|
+
}
|
|
2039
|
+
else
|
|
2040
|
+
{
|
|
2041
|
+
FinalProp = Prop;
|
|
2009
2042
|
}
|
|
2010
2043
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2044
|
+
|
|
2045
|
+
if (FinalProp)
|
|
2046
|
+
{
|
|
2047
|
+
void* ValuePtr = FinalProp->ContainerPtrToValuePtr<void>(CurrentContainer);
|
|
2048
|
+
FinalProp->ImportText_Direct(*DefaultValue, ValuePtr, nullptr, PPF_None);
|
|
2049
|
+
TargetNode->PostEditChange();
|
|
2050
|
+
bSetViaProperty = true;
|
|
2051
|
+
}
|
|
2015
2052
|
}
|
|
2016
2053
|
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2054
|
+
if (!bSetViaPin && !bSetViaProperty)
|
|
2055
|
+
{
|
|
2056
|
+
// Neither pin nor property found — build a helpful error
|
|
2057
|
+
TArray<FString> PinNames;
|
|
2058
|
+
for (UEdGraphPin* Pin : TargetNode->Pins)
|
|
2059
|
+
{
|
|
2060
|
+
if (Pin) PinNames.Add(Pin->PinName.ToString());
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
TArray<FString> PropNames;
|
|
2064
|
+
for (TFieldIterator<FProperty> It(TargetNode->GetClass()); It; ++It)
|
|
2065
|
+
{
|
|
2066
|
+
PropNames.Add(It->GetName());
|
|
2067
|
+
}
|
|
2020
2068
|
|
|
2021
|
-
|
|
2022
|
-
|
|
2069
|
+
Result->SetStringField(TEXT("error"), FString::Printf(
|
|
2070
|
+
TEXT("'%s' not found as pin or property. Pins: [%s]. Properties: [%s]"),
|
|
2071
|
+
*PinName, *FString::Join(PinNames, TEXT(", ")), *FString::Join(PropNames, TEXT(", "))));
|
|
2072
|
+
Result->SetBoolField(TEXT("success"), false);
|
|
2073
|
+
return MakeShared<FJsonValueObject>(Result);
|
|
2074
|
+
}
|
|
2023
2075
|
|
|
2024
2076
|
// Compile and save
|
|
2025
2077
|
FKismetEditorUtilities::CompileBlueprint(Blueprint);
|
|
@@ -2036,8 +2088,9 @@ TSharedPtr<FJsonValue> FBlueprintHandlers::SetNodeProperty(const TSharedPtr<FJso
|
|
|
2036
2088
|
Result->SetStringField(TEXT("path"), AssetPath);
|
|
2037
2089
|
Result->SetStringField(TEXT("graphName"), GraphName);
|
|
2038
2090
|
Result->SetStringField(TEXT("nodeId"), NodeId);
|
|
2039
|
-
Result->SetStringField(TEXT("
|
|
2040
|
-
Result->SetStringField(TEXT("
|
|
2091
|
+
Result->SetStringField(TEXT("propertyName"), PinName);
|
|
2092
|
+
Result->SetStringField(TEXT("value"), DefaultValue);
|
|
2093
|
+
Result->SetStringField(TEXT("setVia"), bSetViaPin ? TEXT("pin") : TEXT("property"));
|
|
2041
2094
|
Result->SetBoolField(TEXT("success"), true);
|
|
2042
2095
|
|
|
2043
2096
|
return MakeShared<FJsonValueObject>(Result);
|