ue-mcp 1.2.4 → 1.3.0
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 +4 -3
- package/dist/action-class.js +56 -3
- package/dist/action-class.js.map +1 -1
- package/dist/bridge-timeouts.d.ts +64 -0
- package/dist/bridge-timeouts.js +118 -0
- package/dist/bridge-timeouts.js.map +1 -0
- package/dist/bridge.js +10 -2
- package/dist/bridge.js.map +1 -1
- package/dist/editor-control.d.ts +72 -5
- package/dist/editor-control.js +164 -140
- package/dist/editor-control.js.map +1 -1
- package/dist/editor-target.d.ts +55 -1
- package/dist/editor-target.js +107 -10
- package/dist/editor-target.js.map +1 -1
- package/dist/engine-observer.d.ts +59 -5
- package/dist/engine-observer.js +249 -29
- package/dist/engine-observer.js.map +1 -1
- package/dist/engine-root.d.ts +91 -0
- package/dist/engine-root.js +448 -0
- package/dist/engine-root.js.map +1 -0
- package/dist/epic-enrich.js +16 -1
- package/dist/epic-enrich.js.map +1 -1
- package/dist/feedback-cli.js +4 -0
- package/dist/feedback-cli.js.map +1 -1
- package/dist/feedback-deferred.d.ts +9 -0
- package/dist/feedback-deferred.js +2 -0
- package/dist/feedback-deferred.js.map +1 -1
- package/dist/feedback-fallback.d.ts +99 -0
- package/dist/feedback-fallback.js +173 -0
- package/dist/feedback-fallback.js.map +1 -0
- package/dist/flow/write-methods.js +20 -0
- package/dist/flow/write-methods.js.map +1 -1
- package/dist/lean-context.js +8 -3
- package/dist/lean-context.js.map +1 -1
- package/dist/locking.js +11 -2
- package/dist/locking.js.map +1 -1
- package/dist/project.d.ts +11 -0
- package/dist/project.js +23 -2
- package/dist/project.js.map +1 -1
- package/dist/python-gate.d.ts +95 -0
- package/dist/python-gate.js +175 -0
- package/dist/python-gate.js.map +1 -0
- package/dist/tool-counts.json +16 -16
- package/dist/tools/animation.js +288 -24
- package/dist/tools/animation.js.map +1 -1
- package/dist/tools/asset.js +79 -14
- package/dist/tools/asset.js.map +1 -1
- package/dist/tools/audio.js +59 -5
- package/dist/tools/audio.js.map +1 -1
- package/dist/tools/blueprint.js +29 -12
- package/dist/tools/blueprint.js.map +1 -1
- package/dist/tools/chooser.js +4 -1
- package/dist/tools/chooser.js.map +1 -1
- package/dist/tools/editor.js +81 -43
- package/dist/tools/editor.js.map +1 -1
- package/dist/tools/feedback.js +214 -48
- package/dist/tools/feedback.js.map +1 -1
- package/dist/tools/foliage.js +27 -1
- package/dist/tools/foliage.js.map +1 -1
- package/dist/tools/gameplay.js +38 -11
- package/dist/tools/gameplay.js.map +1 -1
- package/dist/tools/gas.js +17 -5
- package/dist/tools/gas.js.map +1 -1
- package/dist/tools/landscape.js +22 -7
- package/dist/tools/landscape.js.map +1 -1
- package/dist/tools/level.js +322 -51
- package/dist/tools/level.js.map +1 -1
- package/dist/tools/material.js +10 -4
- package/dist/tools/material.js.map +1 -1
- package/dist/tools/niagara.js +3 -2
- package/dist/tools/niagara.js.map +1 -1
- package/dist/tools/pcg.js +6 -5
- package/dist/tools/pcg.js.map +1 -1
- package/dist/tools/project.js +47 -20
- package/dist/tools/project.js.map +1 -1
- package/dist/types.d.ts +21 -0
- package/dist/types.js +46 -3
- package/dist/types.js.map +1 -1
- package/dist/ue-mcp.default.yml +493 -125
- package/package.json +2 -2
- package/plugin/ue_mcp_bridge/NATIVE_RUNTIME_VISIBILITY.md +53 -0
- package/plugin/ue_mcp_bridge/NATIVE_STATIC_MESH_USAGE_PROGRESS.md +115 -0
- package/plugin/ue_mcp_bridge/README_MassHandlers.md +97 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/BridgeServer.cpp +14 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.cpp +21 -4
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.h +9 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerJsonProperty.h +395 -69
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.cpp +79 -3
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.h +25 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_ControlRig.cpp +3 -3
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_ControlRigSequencer.cpp +3061 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_IKRetargeterAuthoring.cpp +961 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_IKRigAuthoring.cpp +900 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Pose.cpp +769 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Sequence.cpp +44 -3
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_SkeletalLive.cpp +217 -11
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_StateMachine.cpp +551 -24
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Validation.cpp +735 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.cpp +352 -73
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.h +8 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkProperties.cpp +1 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkRead.cpp +503 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkRead.h +21 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkUpsert.cpp +2 -2
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Enum.cpp +2 -2
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Geometry.cpp +902 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Geometry.h +33 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Import.cpp +478 -134
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Mesh.cpp +5 -5
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_MeshBoolean.cpp +933 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_MeshBoolean.h +35 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Redirectors.cpp +478 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_RenderTarget.cpp +1 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Sockets.cpp +4 -4
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Struct.cpp +2 -2
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Subobject.cpp +319 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AudioHandlers_SoundCue.cpp +3 -3
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.cpp +482 -35
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.h +10 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Collision.cpp +502 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Collision.h +43 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Functions.cpp +89 -7
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Graph.cpp +17 -51
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Internal.h +107 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Properties.cpp +10 -10
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Search.cpp +648 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DemoHandlers.cpp +5 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DiffHandlers.cpp +252 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DiffHandlers.h +10 -2
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.cpp +252 -41
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.h +4 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_Build.cpp +250 -27
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_PIE.cpp +303 -125
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_PIERuntime.cpp +73 -50
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_RuntimeVisibility.cpp +757 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.cpp +11 -2
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.h +3 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers_Batch.cpp +419 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.cpp +39 -161
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.h +66 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers_BTAuthoring.cpp +1323 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers_BehaviorTree.cpp +1211 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.cpp +2 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.h +60 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers_Runtime.cpp +363 -12
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/HandlerEditorState.h +84 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.cpp +1288 -36
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.h +3 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers_Sculpt.cpp +41 -16
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.cpp +959 -213
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.h +66 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_BatchWrite.cpp +1571 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Convert.cpp +316 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Inspection.cpp +280 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_InstanceProjection.cpp +666 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_InstanceProjection_Internal.h +63 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Lights.cpp +43 -12
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_MultiLevel.cpp +13 -47
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_PostProcess.cpp +527 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Query.cpp +1169 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Refresh.cpp +723 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Save.cpp +325 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Spatial.cpp +360 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Trace.cpp +178 -58
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Transient.cpp +337 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Volumes.cpp +25 -12
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_WorldPartition.cpp +10 -9
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_WorldPartitionSettings.cpp +686 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MassHandlers.cpp +467 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MassHandlers.h +22 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.cpp +452 -175
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.h +5 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers_Build.cpp +597 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NiagaraHandlers.cpp +17 -15
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PCGHandlers.cpp +38 -168
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PhysicsHandlers.cpp +39 -30
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.cpp +392 -78
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.h +2 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers_Internal.h +83 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SkeletalMeshHandlers.cpp +200 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SkeletalMeshHandlers.h +15 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.cpp +19 -12
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/StateTreeHandlers.cpp +31 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.cpp +307 -69
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.h +84 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers_Extraction.cpp +8 -41
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers_Properties.cpp +33 -52
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/ActorSelectorTests.cpp +344 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AnimationControlRigTimelineTests.cpp +60 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AnimationPoseTests.cpp +115 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetBulkReadTests.cpp +177 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetDeleteGuardTests.cpp +276 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetPathResolutionTests.cpp +243 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetPropertyPersistTests.cpp +213 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetSubobjectTests.cpp +235 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AutomationRunnerTests.cpp +72 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BehaviorTreeAuthoringTests.cpp +526 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BehaviorTreeNodeTests.cpp +334 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BlueprintHandlerSurfaceTests.cpp +362 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BridgeProtocolTests.cpp +14 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/CollisionQueryTests.cpp +288 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/DataTableRowWriteTests.cpp +453 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/EditorFunctionCallTests.cpp +223 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/FoliageBatchTests.cpp +147 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/GameThreadGateTests.cpp +82 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/GasLiveAttributeTests.cpp +183 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LandscapeSampleTests.cpp +119 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelBatchWriteTests.cpp +176 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelComponentTreeInstanceCountTests.cpp +189 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelConvertBrushesTests.cpp +100 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelInstanceProjectionTests.cpp +265 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelPostProcessOverrideTests.cpp +258 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelQueryComponentsTests.cpp +195 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelRefreshTests.cpp +142 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelSaveReportTests.cpp +125 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelScriptHandlersTests.cpp +42 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelStaticMeshUsageTests.cpp +412 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelTraceWorldScopeTests.cpp +133 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelTransientActorTests.cpp +205 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelWorldPartitionSettingsTests.cpp +168 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MCPInstancedStructPathTestTypes.h +51 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MCPInstancedStructPathTests.cpp +379 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MaterialBuildTests.cpp +238 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MeshBooleanTests.cpp +170 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MeshGeometryTests.cpp +116 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/PackageSaveExtensionTests.cpp +161 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/PackageWriteGuardTests.cpp +253 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/RuntimeVisibilityTests.cpp +143 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SequencerHandlerTests.cpp +660 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SequencerScrubTests.cpp +50 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SkeletonDiffTests.cpp +685 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/WidgetBlueprintResolveTests.cpp +145 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/UE_MCP_Bridge.cpp +80 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerFunctionCall.h +509 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerQuery.h +407 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerUtils.h +1008 -77
- package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/UE_MCP_Bridge.Build.cs +87 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Private/MCPEngineStatus.cpp +152 -14
- package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Private/Tests/MCPEngineStatusTests.cpp +65 -0
- package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Public/MCPEngineStatus.h +32 -1
- package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/UE_MCP_BridgeStatus.Build.cs +2 -0
- package/skills/ue-mcp-animation/SKILL.md +154 -0
- package/skills/ue-mcp-blueprint/SKILL.md +71 -0
package/dist/tools/animation.js
CHANGED
|
@@ -1,6 +1,226 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { categoryTool, bp } from "../types.js";
|
|
3
3
|
import { Vec3, Quat } from "../schemas.js";
|
|
4
|
+
// Keep the Control Rig operation schema self-contained so adding it does not
|
|
5
|
+
// redirect JSON-schema references used by older animation actions.
|
|
6
|
+
const ControlRigVec3 = z.object({
|
|
7
|
+
x: z.number().finite(),
|
|
8
|
+
y: z.number().finite(),
|
|
9
|
+
z: z.number().finite(),
|
|
10
|
+
}).strict();
|
|
11
|
+
const ControlRigRotator = z.object({ pitch: z.number(), yaw: z.number(), roll: z.number() }).strict();
|
|
12
|
+
const ControlRigQuaternion = z.object({
|
|
13
|
+
x: z.number().finite(),
|
|
14
|
+
y: z.number().finite(),
|
|
15
|
+
z: z.number().finite(),
|
|
16
|
+
w: z.number().finite(),
|
|
17
|
+
}).strict().refine((rotation) => Math.abs(Math.hypot(rotation.x, rotation.y, rotation.z, rotation.w) - 1) <= 1e-3, { message: "rotationQuaternion must be normalized" });
|
|
18
|
+
const ControlRigKeyTransform = z.object({
|
|
19
|
+
translation: ControlRigVec3,
|
|
20
|
+
rotationDegrees: ControlRigRotator,
|
|
21
|
+
scale: ControlRigVec3,
|
|
22
|
+
}).strict();
|
|
23
|
+
const ControlRigSetEdit = z.object({
|
|
24
|
+
op: z.literal("set"),
|
|
25
|
+
control: z.string().min(1),
|
|
26
|
+
frame: z.number().int().optional(),
|
|
27
|
+
frames: z.array(z.number().int()).min(1).optional(),
|
|
28
|
+
transform: ControlRigKeyTransform,
|
|
29
|
+
space: z.enum(["local", "global"]).optional(),
|
|
30
|
+
}).strict().refine((edit) => (edit.frame === undefined) !== (edit.frames === undefined), { message: "set operations require exactly one of frame or frames" });
|
|
31
|
+
const ControlRigTransformKey = z.object({
|
|
32
|
+
frame: z.number().int(),
|
|
33
|
+
transform: z.object({
|
|
34
|
+
translation: ControlRigVec3,
|
|
35
|
+
rotationQuaternion: ControlRigQuaternion,
|
|
36
|
+
scale: ControlRigVec3,
|
|
37
|
+
}).strict(),
|
|
38
|
+
}).strict();
|
|
39
|
+
const ControlRigSetKeysEdit = z.object({
|
|
40
|
+
op: z.literal("set_keys"),
|
|
41
|
+
control: z.string().min(1),
|
|
42
|
+
keys: z.array(ControlRigTransformKey).min(1),
|
|
43
|
+
space: z.enum(["local", "global"]).optional(),
|
|
44
|
+
}).strict().refine((edit) => edit.keys.every((key, index) => index === 0 || key.frame > edit.keys[index - 1].frame), { message: "set_keys frames must be strictly increasing" });
|
|
45
|
+
const ControlRigOffsetEdit = z.object({
|
|
46
|
+
op: z.literal("offset"),
|
|
47
|
+
control: z.string().min(1),
|
|
48
|
+
startFrame: z.number().int(),
|
|
49
|
+
endFrame: z.number().int(),
|
|
50
|
+
translationCm: ControlRigVec3.optional(),
|
|
51
|
+
rotationDegrees: ControlRigRotator.optional(),
|
|
52
|
+
scaleMultiplier: ControlRigVec3.optional(),
|
|
53
|
+
space: z.enum(["local", "global"]).optional(),
|
|
54
|
+
blendInFrames: z.number().int().nonnegative().optional(),
|
|
55
|
+
blendOutFrames: z.number().int().nonnegative().optional(),
|
|
56
|
+
}).strict()
|
|
57
|
+
.refine((edit) => edit.endFrame >= edit.startFrame, {
|
|
58
|
+
message: "offset endFrame must be greater than or equal to startFrame",
|
|
59
|
+
})
|
|
60
|
+
.refine((edit) => edit.translationCm !== undefined || edit.rotationDegrees !== undefined || edit.scaleMultiplier !== undefined, { message: "offset operations require translationCm, rotationDegrees, or scaleMultiplier" });
|
|
61
|
+
const ControlRigContactTarget = z.object({
|
|
62
|
+
translation: ControlRigVec3,
|
|
63
|
+
rotationQuaternion: ControlRigQuaternion.optional(),
|
|
64
|
+
}).strict();
|
|
65
|
+
const ControlRigContactLockEdit = z.object({
|
|
66
|
+
op: z.literal("contact_lock"),
|
|
67
|
+
control: z.string().min(1),
|
|
68
|
+
drivenReference: z.string().min(1).optional(),
|
|
69
|
+
startFrame: z.number().int(),
|
|
70
|
+
endFrame: z.number().int(),
|
|
71
|
+
target: ControlRigContactTarget,
|
|
72
|
+
blendInFrames: z.number().int().nonnegative().optional(),
|
|
73
|
+
blendOutFrames: z.number().int().nonnegative().optional(),
|
|
74
|
+
stabilizeControls: z.array(z.string().min(1)).max(8).optional(),
|
|
75
|
+
positionToleranceCm: z.number().finite().positive().max(100).optional(),
|
|
76
|
+
rotationToleranceDegrees: z.number().finite().positive().max(180).optional(),
|
|
77
|
+
}).strict().superRefine((edit, context) => {
|
|
78
|
+
if (edit.endFrame < edit.startFrame) {
|
|
79
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["endFrame"], message: "contact_lock endFrame must be at least startFrame" });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const intervalCount = edit.endFrame - edit.startFrame;
|
|
83
|
+
const blendIn = edit.blendInFrames ?? 0;
|
|
84
|
+
const blendOut = edit.blendOutFrames ?? 0;
|
|
85
|
+
if (blendIn + blendOut > intervalCount) {
|
|
86
|
+
context.addIssue({
|
|
87
|
+
code: z.ZodIssueCode.custom,
|
|
88
|
+
path: ["blendOutFrames"],
|
|
89
|
+
message: "contact_lock blends must leave at least one fully constrained frame",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const controlKey = edit.control.toLowerCase();
|
|
93
|
+
const stabilizerKeys = (edit.stabilizeControls ?? []).map((control) => control.toLowerCase());
|
|
94
|
+
if (stabilizerKeys.includes(controlKey)) {
|
|
95
|
+
context.addIssue({
|
|
96
|
+
code: z.ZodIssueCode.custom,
|
|
97
|
+
path: ["stabilizeControls"],
|
|
98
|
+
message: "contact_lock control cannot also be a stabilizer",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (new Set(stabilizerKeys).size !== stabilizerKeys.length) {
|
|
102
|
+
context.addIssue({
|
|
103
|
+
code: z.ZodIssueCode.custom,
|
|
104
|
+
path: ["stabilizeControls"],
|
|
105
|
+
message: "contact_lock stabilizers must be unique",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const frameCount = intervalCount + 1;
|
|
109
|
+
if (frameCount * (stabilizerKeys.length + 1) > 100_000) {
|
|
110
|
+
context.addIssue({
|
|
111
|
+
code: z.ZodIssueCode.custom,
|
|
112
|
+
path: ["endFrame"],
|
|
113
|
+
message: "contact_lock is limited to 100000 control-frame cells",
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
const ControlRigSetBoolEdit = z.object({
|
|
118
|
+
op: z.literal("set_bool"),
|
|
119
|
+
control: z.string().min(1),
|
|
120
|
+
frame: z.number().int().optional(),
|
|
121
|
+
frames: z.array(z.number().int()).min(1).optional(),
|
|
122
|
+
value: z.boolean(),
|
|
123
|
+
}).strict().refine((edit) => (edit.frame === undefined) !== (edit.frames === undefined), { message: "set_bool operations require exactly one of frame or frames" });
|
|
124
|
+
const ControlRigSetFloatEdit = z.object({
|
|
125
|
+
op: z.literal("set_float"),
|
|
126
|
+
control: z.string().min(1),
|
|
127
|
+
frame: z.number().int().optional(),
|
|
128
|
+
frames: z.array(z.number().int()).min(1).optional(),
|
|
129
|
+
value: z.number().finite(),
|
|
130
|
+
}).strict().refine((edit) => (edit.frame === undefined) !== (edit.frames === undefined), { message: "set_float operations require exactly one of frame or frames" });
|
|
131
|
+
const ControlRigSetIntEdit = z.object({
|
|
132
|
+
op: z.literal("set_int"),
|
|
133
|
+
control: z.string().min(1),
|
|
134
|
+
frame: z.number().int().optional(),
|
|
135
|
+
frames: z.array(z.number().int()).min(1).optional(),
|
|
136
|
+
value: z.number().int(),
|
|
137
|
+
}).strict().refine((edit) => (edit.frame === undefined) !== (edit.frames === undefined), { message: "set_int operations require exactly one of frame or frames" });
|
|
138
|
+
const ControlRigEditOperation = z.union([
|
|
139
|
+
ControlRigSetEdit,
|
|
140
|
+
ControlRigSetKeysEdit,
|
|
141
|
+
ControlRigOffsetEdit,
|
|
142
|
+
ControlRigContactLockEdit,
|
|
143
|
+
ControlRigSetBoolEdit,
|
|
144
|
+
ControlRigSetFloatEdit,
|
|
145
|
+
ControlRigSetIntEdit,
|
|
146
|
+
]);
|
|
147
|
+
const IKRigAuthoringChain = z.object({
|
|
148
|
+
name: z.string().min(1),
|
|
149
|
+
startBone: z.string().min(1),
|
|
150
|
+
endBone: z.string().min(1),
|
|
151
|
+
goal: z.string().min(1).optional(),
|
|
152
|
+
}).strict();
|
|
153
|
+
const IKRigFullBodyGoal = z.object({
|
|
154
|
+
name: z.string().min(1),
|
|
155
|
+
bone: z.string().min(1),
|
|
156
|
+
positionAlpha: z.number().finite().min(0).max(1).optional(),
|
|
157
|
+
rotationAlpha: z.number().finite().min(0).max(1).optional(),
|
|
158
|
+
chainDepth: z.number().int().nonnegative().optional(),
|
|
159
|
+
strengthAlpha: z.number().finite().min(0).max(1).optional(),
|
|
160
|
+
pullChainAlpha: z.number().finite().min(0).max(1).optional(),
|
|
161
|
+
pinRotation: z.number().finite().min(0).max(1).optional(),
|
|
162
|
+
}).strict();
|
|
163
|
+
const IKRigFullBodySettings = z.object({
|
|
164
|
+
solverIndex: z.number().int().nonnegative().optional(),
|
|
165
|
+
rootBone: z.string().min(1),
|
|
166
|
+
enabled: z.boolean().optional(),
|
|
167
|
+
goals: z.array(IKRigFullBodyGoal).min(1).max(256),
|
|
168
|
+
}).strict();
|
|
169
|
+
const IKRigExclusion = z.object({
|
|
170
|
+
bone: z.string().min(1),
|
|
171
|
+
excluded: z.boolean(),
|
|
172
|
+
}).strict();
|
|
173
|
+
const IKRetargetChainMapping = z.object({
|
|
174
|
+
targetChain: z.string().min(1),
|
|
175
|
+
sourceChain: z.string().min(1).nullable().optional(),
|
|
176
|
+
}).strict();
|
|
177
|
+
const IKRetargetPose = z.object({
|
|
178
|
+
side: z.enum(["source", "target"]),
|
|
179
|
+
name: z.string().min(1),
|
|
180
|
+
create: z.boolean().optional(),
|
|
181
|
+
reset: z.boolean().optional(),
|
|
182
|
+
autoAlign: z.enum(["chain_to_chain", "mesh_to_mesh", "local_axes", "global_axes"]).optional(),
|
|
183
|
+
bones: z.array(z.string().min(1)).max(10_000).optional(),
|
|
184
|
+
rotationOffsets: z.array(z.object({
|
|
185
|
+
bone: z.string().min(1),
|
|
186
|
+
rotationQuaternion: ControlRigQuaternion,
|
|
187
|
+
}).strict()).max(10_000).optional(),
|
|
188
|
+
rootOffsetZ: z.number().finite().optional(),
|
|
189
|
+
snapBoneToGround: z.string().min(1).optional(),
|
|
190
|
+
}).strict().refine((pose) => pose.rootOffsetZ === undefined || pose.snapBoneToGround === undefined, { message: "retarget pose rootOffsetZ and snapBoneToGround are mutually exclusive" });
|
|
191
|
+
/**
|
|
192
|
+
* Element schemas for the Motion Matching authoring arrays (#936).
|
|
193
|
+
*
|
|
194
|
+
* These were `z.array(z.any())`, which serialises to an array schema with no
|
|
195
|
+
* `items`; VS Code refuses to load a tool that carries one. Each object stays
|
|
196
|
+
* open (`.passthrough()`) so nothing a caller sends today is dropped, and the
|
|
197
|
+
* entries that the handler also accepts as a bare string keep that spelling
|
|
198
|
+
* through a union rather than an untyped element.
|
|
199
|
+
*/
|
|
200
|
+
/** set_pose_search_clips: one clip entry. The handler accepts any of the four path spellings. */
|
|
201
|
+
const PoseSearchClipEntry = z.object({
|
|
202
|
+
sequencePath: z.string().optional().describe("Animation asset path (aliases: asset, assetPath, animationPath)"),
|
|
203
|
+
asset: z.string().optional().describe("Alias for sequencePath"),
|
|
204
|
+
assetPath: z.string().optional().describe("Alias for sequencePath"),
|
|
205
|
+
animationPath: z.string().optional().describe("Alias for sequencePath"),
|
|
206
|
+
mirror: z.string().optional().describe("'original' | 'mirrored' | 'both'"),
|
|
207
|
+
disableReselection: z.boolean().optional().describe("Disallow reselecting poses from the same asset"),
|
|
208
|
+
sampleStart: z.number().optional().describe("Sampling range start in seconds"),
|
|
209
|
+
sampleEnd: z.number().optional().describe("Sampling range end in seconds"),
|
|
210
|
+
enabled: z.boolean().optional().describe("Include the clip in the database"),
|
|
211
|
+
}).passthrough();
|
|
212
|
+
/** add_pose_search_schema_pose_channel: one sampled bone. */
|
|
213
|
+
const PoseSearchBoneEntry = z.object({
|
|
214
|
+
bone: z.string().describe("Bone name"),
|
|
215
|
+
flags: z.array(z.string()).optional().describe("Any of: velocity, position, rotation, phase"),
|
|
216
|
+
weight: z.number().optional().describe("Per-bone weight (default 1)"),
|
|
217
|
+
}).passthrough();
|
|
218
|
+
/** create_mirror_data_table: one find/replace bone-name rule. */
|
|
219
|
+
const MirrorFindReplaceExpression = z.object({
|
|
220
|
+
find: z.string().describe("Bone-name fragment to match"),
|
|
221
|
+
replace: z.string().describe("Replacement fragment"),
|
|
222
|
+
method: z.string().optional().describe("suffix (default) | prefix | regex"),
|
|
223
|
+
}).passthrough();
|
|
4
224
|
export const animationTool = categoryTool("animation", "Animation assets, skeletons, montages, blendspaces, anim blueprints, physics assets.", {
|
|
5
225
|
read_anim_blueprint: bp("Read AnimBP structure. Params: assetPath", "read_anim_blueprint"),
|
|
6
226
|
read_montage: bp("Read montage. Params: assetPath", "read_anim_montage", (p) => ({ assetPath: p.assetPath })),
|
|
@@ -16,7 +236,7 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
16
236
|
create_blendspace: bp("Create blendspace (2D). Params: skeletonPath, name?, packagePath?, axisHorizontal?, axisVertical?", "create_blendspace"),
|
|
17
237
|
create_blendspace_1d: bp("Create BlendSpace1D. Params: skeletonPath, name?, packagePath?, axisName? (default Speed), axisMin?, axisMax?, gridNum? (#459)", "create_blendspace_1d", (p) => ({ name: p.name, skeletonPath: p.skeletonPath, packagePath: p.packagePath, axisName: p.axisName, axisMin: p.axisMin, axisMax: p.axisMax, gridNum: p.gridNum, onConflict: p.onConflict })),
|
|
18
238
|
populate_blendspace: bp("One-call axis params + samples authoring for BlendSpace 1D/2D. Params: assetPath, axis? ({name?, min?, max?, gridNum?}) for axis 0, blendspaceAxes? (per-axis array), axisHorizontal?/axisVertical? + horizontalMin/horizontalMax/verticalMin/verticalMax/gridNumHorizontal/gridNumVertical (back-compat), samples ([{animationPath, x, y?}]), clearExisting? (default true) (#459)", "populate_blendspace", (p) => ({ assetPath: p.assetPath, axis: p.axis, axes: p.blendspaceAxes, axisIndex: p.axisIndex, axisHorizontal: p.axisHorizontal, axisVertical: p.axisVertical, horizontalMin: p.horizontalMin, horizontalMax: p.horizontalMax, verticalMin: p.verticalMin, verticalMax: p.verticalMax, gridNumHorizontal: p.gridNumHorizontal, gridNumVertical: p.gridNumVertical, samples: p.samples, clearExisting: p.clearExisting })),
|
|
19
|
-
add_notify: bp("Add notify. For PlayMontageNotify the notifyName is also written onto the spawned notify object so OnPlayMontageNotifyBegin broadcasts it (not 'None'), and montage branching-point markers refresh (#528). notifyProperties writes EditAnywhere fields onto the spawned notify object and therefore requires a notifyClass that resolves. Params: assetPath, notifyName, triggerTime, notifyClass?, notifyProperties?", "add_anim_notify"),
|
|
239
|
+
add_notify: bp("Add notify. For PlayMontageNotify the notifyName is also written onto the spawned notify object so OnPlayMontageNotifyBegin broadcasts it (not 'None'), and montage branching-point markers refresh (#528/#880). On a montage the PlayMontageNotify classes are added as BRANCHING POINT notifies, which is the only tick type UAnimNotify_PlayMontageNotify::BranchingPointNotify runs at, so OnPlayMontageNotifyBegin broadcasts without a montage reload; pass branchingPoint to force it either way, and read branchingPointMarkerCount in the response to see what the montage cached. notifyProperties writes EditAnywhere fields onto the spawned notify object and therefore requires a notifyClass that resolves. Params: assetPath, notifyName, triggerTime, notifyClass?, notifyProperties?", "add_anim_notify"),
|
|
20
240
|
remove_notify: bp("Remove notify(s) by name and/or class. Pass at least one of notifyName/notifyClass; both filters AND. Idempotent: alreadyDeleted=true if no match. Params: assetPath, notifyName?, notifyClass? (#471)", "remove_anim_notify", (p) => ({ assetPath: p.assetPath, notifyName: p.notifyName, notifyClass: p.notifyClass })),
|
|
21
241
|
get_skeleton_info: bp("Read skeleton. Params: assetPath", "get_skeleton_info"),
|
|
22
242
|
list_sockets: bp("List sockets. Params: assetPath", "list_animation_sockets"),
|
|
@@ -47,22 +267,29 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
47
267
|
remove_montage_segment: bp("Remove a segment from a montage slot by index, then relay out the remaining segments and rewrite the montage length. Idempotent: alreadyDeleted=true when the slot already holds no segments. Params: assetPath, segmentIndex, slotName?, slotIndex? (default 0) (#826)", "remove_montage_segment", (p) => ({ assetPath: p.assetPath, segmentIndex: p.segmentIndex, slotName: p.slotName, slotIndex: p.slotIndex })),
|
|
48
268
|
list_montage_segments: bp("List every slot's segments on a montage so a caller can address them by index: animation path, startPos/endPos trim, playRate, loopCount, track position and length per segment, plus the sections with the slot and segment each one links to. Params: assetPath, slotName? (filter to one slot) (#826)", "list_montage_segments", (p) => ({ assetPath: p.assetPath, slotName: p.slotName })),
|
|
49
269
|
create_ik_rig: bp("Create IKRigDefinition asset, optionally with retargetRoot + chains[]. Params: name, skeletalMeshPath, packagePath?, retargetRoot?, chains?: [{name, startBone, endBone, goal?}]", "create_ik_rig"),
|
|
50
|
-
read_ik_rig: bp("Read IK Rig chains,
|
|
270
|
+
read_ik_rig: bp("Read an IK Rig's preview mesh, skeleton roots/bones, ancestry-validated chains and goal assignments, concrete goals, exclusions, and structured solver/FBIK effector state. Params: assetPath", "read_ik_rig"),
|
|
271
|
+
configure_ik_rig: bp("UE 5.8 only. Author an existing IK Rig through UIKRigController with strict bone, ancestry, goal, and setting validation, native readback, one transaction, and checked save; older engines return unsupported_engine_version. autoSetup='retarget' installs the native retarget definition; 'full_body' installs the retarget definition then Full Body IK before requested desired-state upserts. Params: rigPath, autoSetup? ('retarget'|'full_body'), retargetRoot?, rootMotionBone?, chains?: [{name,startBone,endBone,goal?}], fullBodyIK?: {solverIndex?,rootBone,enabled?,goals:[{name,bone,positionAlpha?,rotationAlpha?,chainDepth?,strengthAlpha?,pullChainAlpha?,pinRotation?}]}, exclusions?: [{bone,excluded}].", "configure_ik_rig", (p) => ({ rigPath: p.rigPath, autoSetup: p.autoSetup, retargetRoot: p.retargetRoot, rootMotionBone: p.rootMotionBone, chains: p.chains, fullBodyIK: p.fullBodyIK, exclusions: p.exclusions })),
|
|
51
272
|
list_control_rig_variables: bp("List ControlRig variables and hierarchy. Params: assetPath", "list_control_rig_variables"),
|
|
52
273
|
read_control_rig_graph: bp("Read a Control Rig's RigVM models: every graph with its nodes (name, node path, class), each node's pins (name, pin path, cppType, direction, execute flag, default value, nested sub-pins) and the links between them, plus full member-variable metadata (type, subtype, array-ness, default, public/read-only). list_control_rig_variables only ever reported a node COUNT, which is not enough to verify solver wiring (#774). Params: assetPath, graphName? (substring filter), includePins? (default true), includeDefaults? (default true), includeLinks? (default true), limit? (nodes per graph, default 200)", "read_control_rig_graph", (p) => ({ assetPath: p.assetPath, graphName: p.graphName, includePins: p.includePins, includeDefaults: p.includeDefaults, includeLinks: p.includeLinks, limit: p.limit })),
|
|
53
274
|
read_control_rig_hierarchy: bp("Read a Control Rig's per-element hierarchy metadata: each element's name, type (Bone|Control|Null|Curve...), index, and parent. Params: assetPath (#619)", "read_control_rig_hierarchy", (p) => ({ assetPath: p.assetPath })),
|
|
275
|
+
begin_control_rig_edit: bp("UE 5.8 only. Create a Sequencer Control Rig editing session over a source AnimSequence; native returns unsupported_engine_version on older engines. Baseline first: before this call, reuse or create a Control Rig for the target character, bind/import the exact target skeleton, add the intended controls, author Forward Solve, add Backward/Inverse Solve, verify it with read_control_rig_hierarchy/read_control_rig_graph, and pass an unchanged source round-trip. For a new baseline, the bundled Epic 5.8 controlrig actions include epic_create, epic_import_bones_from_asset, epic_add_control, and epic_add_backward_solve_graph; epic_create alone is not a usable rig. There is no silent fallback to raw bone-key authoring. rigMode='fk' uses UFKControlRig only when generated FK controls are sufficient; rigMode='asset' requires the verified controlRigPath and rejects rigs without inverse execution. bindingTag is the stable natural key for replay. onConflict is skip|error (default error); existing sessions are never modified. layered defaults false. startFrame is inclusive and endFrame is exclusive. Params: sequencePath, skeletalMeshPath, sourceAnimationPath, rigMode ('fk'|'asset'), controlRigPath?, layered?, startFrame?, endFrame?, displayRate?, bindingTag?, onConflict?. Returns the resolved bindingTag/binding GUID, rig, frame range, controls and created/existed status.", "begin_control_rig_edit", (p) => ({ sequencePath: p.sequencePath, skeletalMeshPath: p.skeletalMeshPath, sourceAnimationPath: p.sourceAnimationPath, rigMode: p.rigMode, controlRigPath: p.controlRigPath, layered: p.layered, startFrame: p.startFrame, endFrame: p.endFrame, displayRate: p.displayRate, bindingTag: p.bindingTag, onConflict: p.onConflict })),
|
|
276
|
+
read_control_rig_edit: bp("UE 5.8 only. Read transform, bool, float/scale-float, and integer/enum controls from a Control Rig editing session without changing editor state; native returns unsupported_engine_version on older engines and has no silent fallback. Params: sequencePath, bindingTag, controlNames?, frames?, space? ('local'|'global'). Scalar samples return value instead of transform. Control metadata includes native controlType, animatable, and enum path/options where applicable. Returns session identity, layered mode, range/rate, filtered control metadata, and requested frame samples.", "read_control_rig_edit", (p) => ({ sequencePath: p.sequencePath, bindingTag: p.bindingTag, controlNames: p.controlNames, frames: p.frames, space: p.space })),
|
|
277
|
+
apply_control_rig_edits: bp("UE 5.8 only. Apply typed Control Rig edits in one transaction; native returns unsupported_engine_version on older engines. There is no silent fallback to raw bone tracks. set_keys writes strictly ordered full per-frame transforms from normalized quaternions and preserves shortest-arc quaternion continuity. A set operation writes one full absolute transform at frame or frames. An offset operation applies translation/rotation/scale deltas across an inclusive frame range with optional edge blends. contact_lock densely constrains a translatable driver control, or an optional driven bone/socket reference, to a fixed component-space target with smooth edge blends and optional pole/control stabilization. Driver and stabilizer keys are read back transactionally. A drivenReference contact returns verification='bake_and_analyze_required'; bake it and analyze every constrained frame before accepting the bone/socket result. set_bool, set_float, and set_int key matching scalar controls; enum controls use set_int with one of the integer values reported in enumOptions. Params: sequencePath, bindingTag, operations[] where set_keys={op:'set_keys',control,keys:[{frame,transform:{translation,rotationQuaternion,scale}}],space?}, set={op:'set',control,frame|frames,transform:{translation,rotationDegrees,scale},space?}, offset={op:'offset',control,startFrame,endFrame,translationCm?,rotationDegrees?,scaleMultiplier?,space?,blendInFrames?,blendOutFrames?}, contact_lock={op:'contact_lock',control,drivenReference?,startFrame,endFrame,target:{translation,rotationQuaternion?},blendInFrames?,blendOutFrames?,stabilizeControls?,positionToleranceCm?,rotationToleranceDegrees?}, set_bool={op:'set_bool',control,frame|frames,value}, set_float={op:'set_float',control,frame|frames,value}, or set_int={op:'set_int',control,frame|frames,value}. Sequencer's current interpolation mode is retained. Returns per-operation counts, affected controls/frames, and contactQa summaries; a failed key/readback batch is undone.", "apply_control_rig_edits", (p) => ({ sequencePath: p.sequencePath, bindingTag: p.bindingTag, operations: p.operations })),
|
|
278
|
+
bake_control_rig_edit: bp("UE 5.8 only. Bake the evaluated Control Rig session to a new AnimSequence asset; native returns unsupported_engine_version on older engines and has no raw-track fallback. The source LevelSequence remains unchanged. outputAssetPath is the output natural key; onConflict is skip|error (default error), never overwrite. Key reduction and Sequencer links are not supported yet, so reduceKeys/createLink must be false or omitted. Params: sequencePath, bindingTag, outputAssetPath, frameRate?, reduceKeys?, tolerance?, createLink?, onConflict?. Returns output asset metadata, frame/rate counts, status, and delete-created-asset rollback.", "bake_control_rig_edit", (p) => ({ sequencePath: p.sequencePath, bindingTag: p.bindingTag, outputAssetPath: p.outputAssetPath, frameRate: p.frameRate, reduceKeys: p.reduceKeys, tolerance: p.tolerance, createLink: p.createLink, onConflict: p.onConflict })),
|
|
279
|
+
analyze_animation: bp("Cross-version, data-driven AnimSequence inspection using the native animation APIs available in the compiled engine. Samples an AnimSequence and reports deterministic numeric motion diagnostics without Python or viewport inference. Params: assetPath (required AnimSequence), skeletalMeshPath?, boneNames?, frames?, sampleRate?, loop?, outputDirectory? (must resolve under Project/Saved/Codex/AnimationQA and must not already contain artifacts). Returns source/rate/range metadata, sampled local/component transforms, root-motion and continuity metrics, and any written analysis artifacts.", "analyze_animation", (p) => ({ assetPath: p.assetPath, skeletalMeshPath: p.skeletalMeshPath, boneNames: p.boneNames, frames: p.frames, sampleRate: p.sampleRate, loop: p.loop, outputDirectory: p.outputDirectory })),
|
|
54
280
|
set_root_motion: bp("Set root motion settings on AnimSequence. Params: assetPath, enableRootMotion?, forceRootLock?, useNormalizedRootMotionScale?, rootMotionRootLock?", "set_root_motion_settings", (p) => ({ path: p.assetPath, enableRootMotion: p.enableRootMotion, forceRootLock: p.forceRootLock, useNormalizedRootMotionScale: p.useNormalizedRootMotionScale, rootMotionRootLock: p.rootMotionRootLock })),
|
|
55
281
|
add_virtual_bone: bp("Add virtual bone. Params: skeletonPath, sourceBone, targetBone", "add_virtual_bone"),
|
|
56
282
|
remove_virtual_bone: bp("Remove virtual bone. Params: skeletonPath, virtualBoneName", "remove_virtual_bone"),
|
|
57
283
|
create_composite: bp("Create AnimComposite. Params: name, skeletonPath, packagePath?", "create_anim_composite"),
|
|
58
284
|
list_modifiers: bp("List applied animation modifiers. Params: assetPath", "list_anim_modifiers", (p) => ({ path: p.assetPath })),
|
|
59
285
|
create_ik_retargeter: bp("Create IKRetargeter asset and (default) initialize the UE 5.7 ops stack: assigns sourceRig+targetRig to all ops, runs AutoMapChains. Returns chainsMapped count. Params: name, packagePath?, sourceRig?, targetRig?, autoMapChains? (default true) (#246)", "create_ik_retargeter", (p) => ({ name: p.name, packagePath: p.packagePath, sourceRig: p.sourceRig, targetRig: p.targetRig, autoMapChains: p.autoMapChains, onConflict: p.onConflict })),
|
|
60
|
-
read_ik_retargeter: bp("Read
|
|
286
|
+
read_ik_retargeter: bp("Read an IK Retargeter's source/target rigs and preview meshes, flattened and per-op chain mappings, typed op stack, and all named/current pose offsets when the compiled engine exposes them. Params: assetPath (#246)", "read_ik_retargeter", (p) => ({ assetPath: p.assetPath })),
|
|
287
|
+
configure_ik_retargeter: bp("UE 5.8 only. Configure an existing IK Retargeter through UIKRetargeterController with the correct default-op and per-op rig assignment order, auto/manual chain mappings, named pose authoring, processor validation, native readback, transaction rollback, and checked save; older engines return unsupported_engine_version. Whole-pose auto-align resets that pose first: create a new pose or pass pose.reset=true to acknowledge replacement, then manual offsets are applied. Params: retargeterPath, sourceRig?, targetRig?, sourcePreviewMesh?, targetPreviewMesh?, ensureDefaultOps? (default true), autoMapMode? ('exact'|'fuzzy'|'clear'), forceRemap? (default false), chainMappings?: [{targetChain,sourceChain?:string|null}], pose?: {side,name,create?,reset?,autoAlign?,bones?,rotationOffsets?:[{bone,rotationQuaternion}],rootOffsetZ?,snapBoneToGround?}.", "configure_ik_retargeter", (p) => ({ retargeterPath: p.retargeterPath, sourceRig: p.sourceRig, targetRig: p.targetRig, sourcePreviewMesh: p.sourcePreviewMesh, targetPreviewMesh: p.targetPreviewMesh, ensureDefaultOps: p.ensureDefaultOps, autoMapMode: p.autoMapMode, forceRemap: p.forceRemap, chainMappings: p.chainMappings, pose: p.pose })),
|
|
61
288
|
set_ik_rig_mesh: bp("Set the preview/source skeletal mesh on an EXISTING IK Rig. Params: rigPath, meshPath (#701)", "set_ik_rig_mesh", (p) => ({ rigPath: p.rigPath, meshPath: p.meshPath })),
|
|
62
289
|
set_ik_retargeter_rig: bp("Set the source or target IK Rig on an EXISTING IK Retargeter. Params: retargeterPath, rigPath, side? (source|target, default target) (#703)", "set_ik_retargeter_rig", (p) => ({ retargeterPath: p.retargeterPath, rigPath: p.rigPath, side: p.side })),
|
|
63
290
|
auto_align_retarget_pose: bp("Auto-align all bones of the source/target retarget pose (chain-to-chain) - fixes a retargeter that outputs a static reference pose. Params: retargeterPath, side? (source|target, default target) (#701)", "auto_align_retarget_pose", (p) => ({ retargeterPath: p.retargeterPath, side: p.side })),
|
|
64
291
|
reset_retarget_pose: bp("Reset the current retarget pose (all bones) to the reference pose. Params: retargeterPath, side? (source|target, default target) (#701)", "reset_retarget_pose", (p) => ({ retargeterPath: p.retargeterPath, side: p.side })),
|
|
65
|
-
batch_retarget_animations: bp("Bake
|
|
292
|
+
batch_retarget_animations: bp("Bake validated source AnimSequences onto the target skeleton through an IK Retargeter (RunBatchRetarget), save every output, and roll back newly created outputs if the batch is incomplete or unsavable. Overwrite is rejected. Returns mapping completeness and every unmapped target chain so partial retargets are explicit; pass requireCompleteMapping=true only when the target should have no intentional extra chains. Params: retargeterPath, sourceMesh, targetMesh, animPaths[], outputPath? (default: alongside source), prefix?, suffix? (default _Retargeted), overwrite? (must be false), requireCompleteMapping? (default false) (#701)", "batch_retarget_animations", (p) => ({ retargeterPath: p.retargeterPath, sourceMesh: p.sourceMesh, targetMesh: p.targetMesh, animPaths: p.animPaths, outputPath: p.outputPath, prefix: p.prefix, suffix: p.suffix, overwrite: p.overwrite, requireCompleteMapping: p.requireCompleteMapping })),
|
|
66
293
|
set_anim_blueprint_skeleton: bp("Set target skeleton on AnimBP. Params: assetPath, skeletonPath", "set_anim_blueprint_skeleton"),
|
|
67
294
|
read_bone_track: bp("Read bone transform samples from AnimSequence. Params: assetPath, boneName, frames?: [int]", "read_bone_track"),
|
|
68
295
|
create_pose_search_database: bp("Create a PoseSearchDatabase asset (motion matching). Params: name, packagePath?, schemaPath?", "create_pose_search_database"),
|
|
@@ -89,10 +316,15 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
89
316
|
set_sequence_properties: bp("Batch-set properties on AnimSequence assets. If a path is a Montage and resolveFromMontages is true (default), resolves to its first AnimSequence. Params: assetPaths[], properties{enableRootMotion?, forceRootLock?, useNormalizedRootMotionScale?, rootMotionRootLock?}, resolveFromMontages?", "set_sequence_properties"),
|
|
90
317
|
bake_root_motion_from_bone: bp("Bake delta translation from a source bone (e.g. pelvis) onto the root bone across the whole sequence; compensates the source bone so world-space position is unchanged. Params: assetPath, sourceBone, rootBone? (default 'root'), axes? (default ['x','y']), interpolation? ('linear'|'per_frame', default 'linear')", "bake_root_motion_from_bone"),
|
|
91
318
|
// #419/#420 - live-actor skeletal operations (moved from level for proper domain alignment)
|
|
92
|
-
get_bone_transform: bp("Read a bone or socket transform on a live actor's SkeletalMeshComponent. Wraps GetBoneTransform / GetSocketTransform. Params: actorLabel, boneName (or socket name), componentName? (default: CharacterMesh0 / Mesh / first SK component), world? (auto|pie|game|editor, default auto), space? (world|component|local, default world). Returns location, rotation, scale (#420)", "get_bone_transform", (p) => ({ actorLabel: p.actorLabel, boneName: p.boneName, componentName: p.componentName, world: p.world, space: p.space })),
|
|
93
|
-
list_bones: bp("List bones in a live actor's SkeletalMeshComponent ref skeleton (name, index, parent). Params: actorLabel, componentName?, world? (auto|pie|game|editor, default auto) (#420)", "list_bones", (p) => ({ actorLabel: p.actorLabel, componentName: p.componentName, world: p.world })),
|
|
94
|
-
rebind_leader_pose: bp("Re-bind every secondary SkeletalMeshComponent on an actor to a body component (default CharacterMesh0 / Mesh). One-call fix for the 'character explodes after rotating the actor' failure mode. Params: actorLabel, bodyComponent? (#419)", "rebind_leader_pose", (p) => ({ actorLabel: p.actorLabel, bodyComponent: p.bodyComponent })),
|
|
95
|
-
|
|
319
|
+
get_bone_transform: bp("Read a bone or socket transform on a live actor's SkeletalMeshComponent. Wraps GetBoneTransform / GetSocketTransform. Params: actorLabel OR actorPath, boneName (or socket name), componentName? (default: CharacterMesh0 / Mesh / first SK component), world? (auto|pie|game|editor, default auto), space? (world|component|local, default world). Returns location, rotation, scale (#420)", "get_bone_transform", (p) => ({ actorLabel: p.actorLabel, actorPath: p.actorPath, boneName: p.boneName, componentName: p.componentName, world: p.world, space: p.space })),
|
|
320
|
+
list_bones: bp("List bones in a live actor's SkeletalMeshComponent ref skeleton (name, index, parent). Params: actorLabel OR actorPath, componentName?, world? (auto|pie|game|editor, default auto) (#420)", "list_bones", (p) => ({ actorLabel: p.actorLabel, actorPath: p.actorPath, componentName: p.componentName, world: p.world })),
|
|
321
|
+
rebind_leader_pose: bp("Re-bind every secondary SkeletalMeshComponent on an actor to a body component (default CharacterMesh0 / Mesh). One-call fix for the 'character explodes after rotating the actor' failure mode. Params: actorLabel OR actorPath, bodyComponent? (#419)", "rebind_leader_pose", (p) => ({ actorLabel: p.actorLabel, actorPath: p.actorPath, bodyComponent: p.bodyComponent })),
|
|
322
|
+
// #922/#923/#926 - evaluated pose reads. Everything above this line reads
|
|
323
|
+
// either raw local-space tracks or the reference pose; these evaluate.
|
|
324
|
+
sample_pose: bp("Evaluate an AnimSequence (or a BlendSpace at a blend position) and return COMPOSED bone transforms, which read_bone_track (raw local space) and get_bone_transforms (reference pose only) cannot give. Params: assetPath, boneNames? (omit for every bone), frames? or times? (omit for every sampled key), space? (component default | local | world), skeletalMeshPath? (evaluate with that mesh's proportions), incorporateRootMotion? (default true), blendPosition? {x,y,z} (BlendSpace only). Returns samples:[{frame, time, bones:[{name, location, rotation, scale}]}]. A montage is refused with a pointer to its segments, because a montage has no pose of its own (#923/#926/#922)", "sample_pose", (p) => ({ assetPath: p.assetPath ?? p.path, boneNames: p.boneNames, frames: p.frames, times: p.times, space: p.space, skeletalMeshPath: p.skeletalMeshPath, incorporateRootMotion: p.incorporateRootMotion, blendPosition: p.blendPosition })),
|
|
325
|
+
get_live_bone_transforms: bp("Read the EVALUATED pose off a live SkeletalMeshComponent in the editor world or PIE, for many bones at once. This is the read that tells 'standing' from 'prone' when the reference pose cannot (#922). Also returns componentTransform and an evaluation block (animationMode, animInstanceClass, componentSpaceTransformCount) so a clean component transform sitting on a dead anim instance is visible in one call. Params: actorLabel OR actorPath, componentName? (default CharacterMesh0 / Mesh), boneNames? (omit for every bone, max 1000), space? (world default | component | local), world? (auto|pie|game|editor) (#922/#926)", "get_live_bone_transforms", (p) => ({ actorLabel: p.actorLabel, actorPath: p.actorPath, componentName: p.componentName, boneNames: p.boneNames, space: p.space, world: p.world })),
|
|
326
|
+
measure_natural_speed: bp("Measure a locomotion clip's planted-foot speed, in cm/s, by evaluating the pose and tracking the lowest foot's horizontal travel while it is in contact. Every retarget changes natural speed by the target skeleton's leg-length ratio, so a BlendSpace built on retargeted clips has to re-measure per clip per character (#923). Params: assetPath, footBones[] (e.g. ['foot_l','foot_r']), contactThreshold? (contact height in cm; omit to derive it from the clip), skeletalMeshPath?, frames?/times?, blendPosition? (BlendSpace only). Returns naturalSpeed, plantedDistance, plantedTime, contactThreshold, per-foot breakdown", "measure_natural_speed", (p) => ({ assetPath: p.assetPath ?? p.path, footBones: p.footBones, contactThreshold: p.contactThreshold, skeletalMeshPath: p.skeletalMeshPath, frames: p.frames, times: p.times, blendPosition: p.blendPosition })),
|
|
327
|
+
preview_animation: bp("Toggle bUpdateAnimationInEditor + VisibilityBasedAnimTickOption=AlwaysTickPoseAndRefreshBones on every SkeletalMeshComponent of an actor. Bypasses the 'cannot be edited on templates' guard for level instances. Params: actorLabel OR actorPath, enabled (#419/#420)", "preview_animation", (p) => ({ actorLabel: p.actorLabel, actorPath: p.actorPath, enabled: p.enabled })),
|
|
96
328
|
}, undefined, {
|
|
97
329
|
assetPath: z.string().optional(),
|
|
98
330
|
directory: z.string().optional(),
|
|
@@ -147,6 +379,7 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
147
379
|
triggerTime: z.number().optional(),
|
|
148
380
|
notifyClass: z.string().optional(),
|
|
149
381
|
notifyProperties: z.record(z.unknown()).optional().describe("add_notify: EditAnywhere fields to set on the spawned notify object (requires notifyClass)"),
|
|
382
|
+
branchingPoint: z.boolean().optional().describe("add_notify: force the montage notify's tick type. Branching-point notifies are the only ones UAnimNotify_PlayMontageNotify::BranchingPointNotify runs, so OnPlayMontageNotifyBegin needs one; the PlayMontageNotify classes default to true on a montage, everything else to the engine's queued tick (#880)"),
|
|
150
383
|
slotIndex: z.number().optional(),
|
|
151
384
|
segmentIndex: z.number().optional().describe("set_montage_sequence: replace only this segment index within the slot (#626). remove_montage_segment: segment to remove. add_montage_section: segment to anchor the section to (#826)"),
|
|
152
385
|
// Montage segment authoring params (#826)
|
|
@@ -160,7 +393,7 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
160
393
|
blendIn: z.number().optional(),
|
|
161
394
|
blendOut: z.number().optional(),
|
|
162
395
|
numFrames: z.number().optional(),
|
|
163
|
-
frameRate: z.number().optional(),
|
|
396
|
+
frameRate: z.number().optional().describe("Frames per second for create_sequence or bake_control_rig_edit."),
|
|
164
397
|
boneName: z.string().optional(),
|
|
165
398
|
boneNames: z.array(z.string()).optional(),
|
|
166
399
|
parentClass: z.string().optional().describe("Parent AnimInstance class name for create_anim_blueprint"),
|
|
@@ -201,7 +434,7 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
201
434
|
startTime: z.number().optional().describe("Start time for montage section"),
|
|
202
435
|
linkedSection: z.string().optional().describe("Next section name to link to"),
|
|
203
436
|
// IK Rig params (#93)
|
|
204
|
-
skeletalMeshPath: z.string().optional().describe("
|
|
437
|
+
skeletalMeshPath: z.string().optional().describe("SkeletalMesh asset path. Used by IK Rig creation, curve/morph comparison, Control Rig edit setup, and animation analysis."),
|
|
205
438
|
animPath: z.string().optional().describe("compare_curves_to_morph_targets: AnimSequence or PoseAsset path (#656)"),
|
|
206
439
|
nodeClass: z.string().optional().describe("inspect_anim_nodes: node class substring filter, e.g. PoseDriver (#657)"),
|
|
207
440
|
enableRootMotion: z.boolean().optional(),
|
|
@@ -212,11 +445,22 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
212
445
|
targetBone: z.string().optional(),
|
|
213
446
|
virtualBoneName: z.string().optional(),
|
|
214
447
|
retargetRoot: z.string().optional().describe("Retarget root bone name for IK Rig"),
|
|
448
|
+
rootMotionBone: z.string().min(1).optional().describe("configure_ik_rig: root-motion bone name"),
|
|
449
|
+
autoSetup: z.enum(["retarget", "full_body"]).optional().describe("configure_ik_rig: optional native rig setup pass"),
|
|
450
|
+
fullBodyIK: IKRigFullBodySettings.optional().describe("configure_ik_rig: Full Body IK solver and desired goal/effector settings"),
|
|
451
|
+
exclusions: z.array(IKRigExclusion).max(2_048).optional().describe("configure_ik_rig: desired per-bone solver exclusions"),
|
|
215
452
|
sourceRig: z.string().optional().describe("Source IKRig path for create_ik_retargeter"),
|
|
216
453
|
targetRig: z.string().optional().describe("Target IKRig path for create_ik_retargeter"),
|
|
217
454
|
rigPath: z.string().optional().describe("IK Rig path for set_ik_rig_mesh / set_ik_retargeter_rig (#701/#703)"),
|
|
218
455
|
meshPath: z.string().optional().describe("Skeletal mesh path for set_ik_rig_mesh (#701)"),
|
|
219
456
|
retargeterPath: z.string().optional().describe("IK Retargeter path (#701/#703)"),
|
|
457
|
+
sourcePreviewMesh: z.string().min(1).optional().describe("configure_ik_retargeter: source preview SkeletalMesh path"),
|
|
458
|
+
targetPreviewMesh: z.string().min(1).optional().describe("configure_ik_retargeter: target preview SkeletalMesh path"),
|
|
459
|
+
ensureDefaultOps: z.boolean().optional().describe("configure_ik_retargeter: ensure the complete UE 5.8 default operation stack; defaults true"),
|
|
460
|
+
autoMapMode: z.enum(["exact", "fuzzy", "clear"]).optional().describe("configure_ik_retargeter: native chain auto-map mode"),
|
|
461
|
+
forceRemap: z.boolean().optional().describe("configure_ik_retargeter: replace existing mappings during auto-map; defaults false"),
|
|
462
|
+
chainMappings: z.array(IKRetargetChainMapping).max(10_000).optional().describe("configure_ik_retargeter: explicit target-to-source chain overrides; null or omitted source clears"),
|
|
463
|
+
pose: IKRetargetPose.optional().describe("configure_ik_retargeter: named source or target pose authoring"),
|
|
220
464
|
side: z.string().optional().describe("source|target for retargeter rig/pose actions (#701/#703)"),
|
|
221
465
|
sourceMesh: z.string().optional().describe("batch_retarget_animations: source skeletal mesh (#701)"),
|
|
222
466
|
targetMesh: z.string().optional().describe("batch_retarget_animations: target skeletal mesh (#701)"),
|
|
@@ -224,16 +468,29 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
224
468
|
prefix: z.string().optional().describe("batch_retarget_animations: output name prefix (#701)"),
|
|
225
469
|
suffix: z.string().optional().describe("batch_retarget_animations: output name suffix (#701)"),
|
|
226
470
|
overwrite: z.boolean().optional().describe("batch_retarget_animations: overwrite existing outputs (#701)"),
|
|
471
|
+
requireCompleteMapping: z.boolean().optional().describe("batch_retarget_animations: reject any unmapped target chain; default false"),
|
|
227
472
|
outputPath: z.string().optional().describe("batch_retarget_animations: destination folder for baked assets (#701)"),
|
|
228
473
|
autoMapChains: z.boolean().optional().describe("create_ik_retargeter: assign rigs to ops + AutoMapChains after creation (default true)"),
|
|
229
|
-
onConflict: z.string().optional().describe("
|
|
230
|
-
frames: z.array(z.number()).optional().describe("
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
474
|
+
onConflict: z.string().optional().describe("Conflict policy. Existing asset actions use skip|error|overwrite; Control Rig begin/bake use skip|error and never overwrite."),
|
|
475
|
+
frames: z.array(z.number()).optional().describe("Frames to read/sample. Used by read_bone_track, read_control_rig_edit, and analyze_animation."),
|
|
476
|
+
// UE 5.8 Control Rig + data-driven animation editing workflow.
|
|
477
|
+
sourceAnimationPath: z.string().optional().describe("begin_control_rig_edit: source AnimSequence asset path (required)."),
|
|
478
|
+
controlRigPath: z.string().optional().describe("begin_control_rig_edit: verified baseline ControlRigBlueprint asset path for this target character; required when rigMode='asset'. Create and validate the rig first when the project/character has none."),
|
|
479
|
+
rigMode: z.enum(["fk", "asset"]).optional().describe("begin_control_rig_edit: use 'asset' with the verified baseline controlRigPath; use 'fk' only when generated raw FK controls are the intended editing surface."),
|
|
480
|
+
layered: z.boolean().optional().describe("begin_control_rig_edit: keep the source animation track active under the Control Rig layer; defaults false."),
|
|
481
|
+
startFrame: z.number().int().optional().describe("begin_control_rig_edit: optional inclusive edit range start frame."),
|
|
482
|
+
endFrame: z.number().int().optional().describe("begin_control_rig_edit: optional exclusive edit range end frame."),
|
|
483
|
+
displayRate: z.number().positive().optional().describe("begin_control_rig_edit: optional LevelSequence display rate in frames per second."),
|
|
484
|
+
bindingTag: z.string().min(1).optional().describe("Stable Control Rig edit-session natural key used by begin/read/apply/bake."),
|
|
485
|
+
controlNames: z.array(z.string().min(1)).min(1).optional().describe("read_control_rig_edit: optional controls to sample; omit to read every control."),
|
|
486
|
+
operations: z.array(ControlRigEditOperation).min(1).optional().describe("apply_control_rig_edits: typed transform/bool/float/int edit operations, including quaternion set_keys."),
|
|
487
|
+
outputAssetPath: z.string().optional().describe("bake_control_rig_edit: required destination AnimSequence asset path."),
|
|
488
|
+
reduceKeys: z.literal(false).optional().describe("bake_control_rig_edit: key reduction is not supported yet; omit or pass false."),
|
|
489
|
+
tolerance: z.number().nonnegative().optional().describe("bake_control_rig_edit: key-reduction tolerance."),
|
|
490
|
+
createLink: z.literal(false).optional().describe("bake_control_rig_edit: Sequencer links are not supported yet; omit or pass false."),
|
|
491
|
+
loop: z.boolean().optional().describe("analyze_animation: include end-to-start loop continuity metrics."),
|
|
492
|
+
outputDirectory: z.string().optional().describe("analyze_animation: optional directory under Project/Saved/Codex/AnimationQA for deterministic artifacts; relative values resolve under that root."),
|
|
493
|
+
chains: z.array(IKRigAuthoringChain).max(256).optional().describe("IK retarget chains for create_ik_rig or configure_ik_rig"),
|
|
237
494
|
keyframes: z.array(z.object({
|
|
238
495
|
frame: z.number(),
|
|
239
496
|
location: Vec3.optional(),
|
|
@@ -252,21 +509,21 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
252
509
|
save: z.boolean().optional().describe("bake_keyframes_batch: save the asset after baking (default true)"),
|
|
253
510
|
// PoseSearch (v0.7.15)
|
|
254
511
|
schemaPath: z.string().optional().describe("Path to a UPoseSearchSchema asset"),
|
|
255
|
-
sequencePath: z.string().optional().describe("Animation
|
|
512
|
+
sequencePath: z.string().optional().describe("Animation path for PoseSearch graph actions, or LevelSequence path for the UE 5.8 Control Rig edit workflow."),
|
|
256
513
|
wait: z.boolean().optional().describe("build_pose_search_index: block until the async build resolves (default true)"),
|
|
257
514
|
// #684 per-clip flags + bulk clip authoring
|
|
258
515
|
mirror: z.string().optional().describe("PoseSearch clip mirror option: 'original' | 'mirrored' | 'both'"),
|
|
259
516
|
disableReselection: z.boolean().optional().describe("PoseSearch clip: disallow reselecting poses from the same asset"),
|
|
260
517
|
sampleStart: z.number().optional().describe("PoseSearch clip sampling range start (seconds); [0,0] = whole clip"),
|
|
261
518
|
sampleEnd: z.number().optional().describe("PoseSearch clip sampling range end (seconds); [0,0] = whole clip"),
|
|
262
|
-
clips: z.array(z.
|
|
519
|
+
clips: z.array(z.union([PoseSearchClipEntry, z.string()])).optional().describe("set_pose_search_clips: array of clip entries ({sequencePath, mirror?, disableReselection?, sampleStart?, sampleEnd?, enabled?}) or bare path strings"),
|
|
263
520
|
// Motion Matching content pipeline (schema / mirror / normalization / tuning)
|
|
264
|
-
sampleRate: z.number().optional().describe("create_pose_search_schema: schema
|
|
521
|
+
sampleRate: z.number().optional().describe("Sample rate. create_pose_search_schema: schema rate (default 30); analyze_animation: optional analysis sampling rate."),
|
|
265
522
|
addDefaultChannels: z.boolean().optional().describe("create_pose_search_schema: add Trajectory+Pose default channels (default true)"),
|
|
266
523
|
mirrorDataTablePath: z.string().optional().describe("create_pose_search_schema: optional MirrorDataTable to bind"),
|
|
267
|
-
bones: z.array(z.
|
|
524
|
+
bones: z.array(z.union([PoseSearchBoneEntry, z.string()])).optional().describe("add_pose_search_schema_pose_channel: [{bone, flags?, weight?}] or bone-name strings; also add_pose_search_schema_trajectory_channel reuses 'samples'"),
|
|
268
525
|
weight: z.number().optional().describe("Channel weight for pose/trajectory channels"),
|
|
269
|
-
expressions: z.array(
|
|
526
|
+
expressions: z.array(MirrorFindReplaceExpression).optional().describe("create_mirror_data_table: [{find, replace, method?}] find/replace bone-name rules"),
|
|
270
527
|
mirrorAxis: z.string().optional().describe("create_mirror_data_table: X, Y or Z (default X)"),
|
|
271
528
|
mirrorRootMotion: z.boolean().optional().describe("create_mirror_data_table: mirror root motion (default true)"),
|
|
272
529
|
databases: z.array(z.string()).optional().describe("create_pose_search_normalization_set: PoseSearchDatabase paths to normalize together"),
|
|
@@ -295,7 +552,7 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
295
552
|
rootBone: z.string().optional().describe("Root bone name for bake_root_motion_from_bone (default 'root')"),
|
|
296
553
|
axes: z.array(z.string()).optional().describe("Axes to bake ('x','y','z') for bake_root_motion_from_bone"),
|
|
297
554
|
interpolation: z.string().optional().describe("bake_root_motion_from_bone: 'linear' (default) or 'per_frame'"),
|
|
298
|
-
space: z.string().optional().describe("
|
|
555
|
+
space: z.string().optional().describe("Transform space. Control Rig edit actions: 'local'|'global'. get_bone_transforms: 'local'|'component'. get_bone_transform: 'world'|'component'|'local'."),
|
|
299
556
|
world: z.string().optional().describe("World scope for live actor skeletal queries: auto (default, prefer PIE), pie/game, or editor"),
|
|
300
557
|
animation: z.string().optional().describe("AnimSequence path for add_blend_sample / set_blend_sample"),
|
|
301
558
|
sampleIndex: z.number().optional().describe("BlendSpace sample index for set_blend_sample"),
|
|
@@ -304,8 +561,15 @@ export const animationTool = categoryTool("animation", "Animation assets, skelet
|
|
|
304
561
|
y: z.number().optional(),
|
|
305
562
|
// Live-actor skeletal operations (moved from level)
|
|
306
563
|
actorLabel: z.string().optional().describe("Actor label for live skeletal queries"),
|
|
564
|
+
actorPath: z.string().optional().describe("Full actor object path. The unambiguous selector, and it wins over actorLabel when both are given. Editor labels are NOT unique, and a label matching several actors is refused with the candidates rather than resolved at random (#983)"),
|
|
307
565
|
componentName: z.string().optional().describe("SkeletalMeshComponent name (default: CharacterMesh0 / Mesh)"),
|
|
308
566
|
bodyComponent: z.string().optional().describe("rebind_leader_pose: explicit body component name"),
|
|
309
567
|
enabled: z.boolean().optional().describe("preview_animation: toggle on/off"),
|
|
568
|
+
// #922/#923/#926 - evaluated pose reads
|
|
569
|
+
times: z.array(z.number()).optional().describe("sample_pose / measure_natural_speed: sample times in seconds; pass either this or 'frames'"),
|
|
570
|
+
incorporateRootMotion: z.boolean().optional().describe("sample_pose: fold the clip's root motion into the returned pose (default true, matching the engine). measure_natural_speed always excludes it, because it measures travel relative to the planted foot"),
|
|
571
|
+
blendPosition: z.object({ x: z.number().optional(), y: z.number().optional(), z: z.number().optional() }).optional().describe("sample_pose / measure_natural_speed: BlendSpace blend input, in the blendspace's own axis units"),
|
|
572
|
+
footBones: z.array(z.string()).optional().describe("measure_natural_speed: the foot bones to track, e.g. ['foot_l','foot_r']"),
|
|
573
|
+
contactThreshold: z.number().optional().describe("measure_natural_speed: height in cm below which a foot counts as planted; omit to derive it from the clip's own lowest foot height, which is what makes the measurement scale-independent across skeletons"),
|
|
310
574
|
});
|
|
311
575
|
//# sourceMappingURL=animation.js.map
|