Skip to content

feat: add UMaterialFunction support to material authoring handlers#352

Closed
nekwo wants to merge 16 commits into
ChiR24:mainfrom
nekwo:feat/material-function-support
Closed

feat: add UMaterialFunction support to material authoring handlers#352
nekwo wants to merge 16 commits into
ChiR24:mainfrom
nekwo:feat/material-function-support

Conversation

@nekwo

@nekwo nekwo commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Material authoring handlers (get_material_info, add_material_node, get_material_node_details, use_material_function) only worked with UMaterial assets. Passing a UMaterialFunction path would fail with ASSET_NOT_FOUND. There was also no way to introspect a material function's inputs and outputs. Additionally, SanitizeProjectRelativePath used a manual /Content/ heuristic for plugin paths that rejected valid game feature plugin mount points.

Changes

  • get_material_info, add_material_node, get_material_node_details now accept both UMaterial and UMaterialFunction paths via a new LoadMaterialOrFunction helper
  • use_material_function supports MF-in-MF calls (placing a function call node inside another material function), with self-reference guard
  • New get_material_function_info sub-action returning function inputs (name, EFunctionInputType, preview/default values, sort priority, description) and outputs
  • Added MCP_GET_FUNCTION_EXPRESSIONS version-compat macro for UE 5.0–5.7+
  • SanitizeProjectRelativePath now uses FPackageName::IsValidLongPackageName instead of manual heuristic, correctly recognizing all registered engine mount points (game feature plugins like /EterniaCore/, /ShooterCore/, /ALS/, etc.)
  • TypeScript handler and tool schema updated with get_material_function_info action
  • CHANGELOG.md updated

Related Issues

None

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 📚 Documentation update
  • 🔧 Configuration/build change
  • ♻️ Refactoring (no functional changes)
  • 🧪 Test addition/update

Testing

  • Tested with Unreal Engine (version: 5.x)
  • Tested MCP client integration (client: Claude Desktop)
  • Added/updated tests

Pre-Merge Checklist

  • Code follows project style guidelines
  • Self-reviewed the code
  • Updated relevant documentation (if needed)
  • Added/updated tests (if applicable)
  • CI passes

Open with Devin

get_material_info, add_material_node, get_material_node_details, and
use_material_function now accept UMaterialFunction paths in addition
to UMaterial. Added get_material_function_info sub-action that returns
function inputs (name, EFunctionInputType, preview values, sort
priority) and outputs. use_material_function supports MF-in-MF calls
with self-reference guard. Includes MCP_GET_FUNCTION_EXPRESSIONS
version-compat macro for UE 5.0-5.7+ and improved path validation
using FPackageName::IsValidLongPackageName.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9c0cf8e0-aeed-4928-8d56-553272e643e8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

👋 Thanks for your first Pull Request! We love contributions. Please ensure you have signed off your commits and followed the contribution guidelines.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

…ies, batch operations

New actions:
- get_node_properties: full property dump per node type (CE code/inputs,
  params, MFC pins, generic UPROPERTY fallback)
- set_static_switch_parameter_value: set static switch on material instances
- delete_node: batch removal with auto-disconnect (single or array)
- update_custom_expression: modify code/inputs/outputs of existing CE
- get_node_chain: BFS path trace between two nodes or to a material pin
- get_connected_subgraph: island detection with orphansOnly flag

Enhanced actions:
- get_node_connections: direction/depth/upstream/downstream graph traversal
  with hop distances, fixes missing output connections
- get_material_info: filter=expressions includes CE code,
  filter=connections supports nodeId/nodeIds filtering
- find_node: deduplicated results with connectionCount
- compile_material: UMaterialFunction fallback
- connect_nodes: MaterialFunctionCall input/output pin iteration
- set_blend_mode/set_shading_model/set_material_domain: graceful MF rejection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added size/xl and removed size/l labels Apr 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📏 Large PR Detected

This pull request is quite large (1000+ lines changed), which can make reviewing challenging.

Suggestions:

  • Consider breaking this into smaller, focused PRs
  • Separate refactoring from new features
  • Split bug fixes from feature additions

This helps reviewers provide better feedback and speeds up the merge process. Thank you! 🙏

devin-ai-integration[bot]

This comment was marked as resolved.

nekwo and others added 2 commits April 14, 2026 09:54
…ndling

GUID-based node IDs caused silent collisions on copy-pasted expressions.
Switch to GetName() (e.g. "MaterialExpressionCustom_0") as canonical ID,
add MCP_NODE_ID() macro, template-based FindExpressionInArray with 5-tier
resolution (expr_N index, object name, GUID backwards-compat with collision
warning, full path, semantic name match).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
auto* range-for fails to deduce type from TObjectPtr elements in UE 5.1+.
Switch to indexed for-loops with explicit static_cast<UMaterialExpression*>.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

@nekwo

nekwo commented Apr 14, 2026

Copy link
Copy Markdown
Contributor Author

sorry for the big pr but material function support is kind of ridiculous in the amount of edge cases for it to be smooth due to things like recursion and node id checks

but claude scripts materials like a beast now

The path normalization pattern `if (!StartsWith("/Game/")) prepend "/Game/"`
clobbered valid plugin mount paths like /EterniaCore/. Since
SanitizeProjectRelativePath already validates against registered engine
mount points via FPackageName::IsValidLongPackageName, only prepend
/Game/ for bare relative paths that lack a leading /.

Also accept 'path' as an alias for 'folder' in all widget creation
handlers (create_widget_blueprint, create_settings_menu, etc.).

Fixed in: WidgetAuthoringHandlers, AudioHandlers, LevelStructureHandlers,
McpAutomationBridgeHelpers.h (ValidateAndBuildAssetPath).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

nekwo and others added 10 commits April 14, 2026 13:05
set_property previously required objectPath which couldn't resolve
Blueprint Class Default Objects (CDO path format Default__ClassName_C
is not findable via standard object resolution).

Now accepts blueprintPath as an alternative — loads the Blueprint,
gets GeneratedClass->GetDefaultObject(), and mutates properties on
the CDO directly. This enables scripted style/theme authoring for
CommonUI button styles and other Blueprint-based data assets.

Also fixes ResolveObjectFromPath to support plugin content mount points
(e.g. /EterniaCore/) — previously only /Game/, /Engine/, /Script/ were
recognized.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ImportText

Uses FProperty::ImportText_Direct for fully reflection-based property
setting on any widget class. Supports two modes:
- Legacy: pass style param to set the Style property (backwards compat)
- Generic: pass propertyName + value to set any property via UE reflection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Read mode: omit value to export current property value via ExportText
- Write mode: Modify() + ImportText + PostEditChangeProperty instead of
  full blueprint recompile (MarkBlueprintAsStructurallyModified only for
  structural changes like clipping)
- Returns exportedValue for write verification
- Validates propertyName instead of value (value empty = read mode)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…operty

Add IsValid() check before accessing Payload fields to prevent null
dereference on malformed requests, matching HandleGetObjectProperty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- set_style: use bHasValueField (field presence) instead of Value.IsEmpty()
  to distinguish read mode (omitted field) from write with empty string
- set_style: coerce JSON number/bool values to string for ImportText
- set_style: add UE 5.0 compat (#if for ImportText vs ImportText_Direct)
- set_style: use MCP_PROPERTY_EXPORT_TEXT macro for ExportText compat
- set_style: restore MarkBlueprintAsStructurallyModified for set_clipping,
  remove unreachable dead else branch
- inspect:set_property: normalize blueprintPath (trim + strip trailing /)
  and add tool context to validation error message
- pipeline-handlers: add 5s timeout to execAsync PATH lookup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nections error, path sanitization

- Rename nodeGuid to nodeId in add_material_node response
- Add AddVerification to connect_material_pins response
- Guard FinalizeHost behind bCleared and report INVALID_PIN for unknown pins
- Add SanitizeProjectRelativePath to all 7 remaining widget template actions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nekwo

nekwo commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

Did all the devin fixes, pushed my other pr to dev by accident, but realized you have coderabbit disabled here.. so i presume you expect it all pushed to dev, let me do that

i was working on main to confirm stability

@nekwo nekwo closed this Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant