Working on MI SetParameter

This commit is contained in:
2026-03-12 08:26:18 -04:00
parent cf9ffc619c
commit 73b5d67b96
12 changed files with 212 additions and 40 deletions

View File

@@ -48,7 +48,6 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
{
if (bError) return *this;
// Split on commas
TArray<FString> Segments;
Path.ParseIntoArray(Segments, TEXT(","));
if (Segments.Num() == 0)
@@ -57,46 +56,33 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
return *this;
}
// If no object yet, first segment is an asset path
int32 Start = 0;
if (!Obj && !ResultPin)
for (int32 i = 0; i < Segments.Num(); i++)
{
LoadUAsset(Segments[0]);
if (bError) return *this;
Start = 1;
}
if (!Obj && !ResultPin)
{
Asset(Segments[i]);
if (bError) return *this;
continue;
}
const TArray<FWalker>& Walkers = GetWalkerTable();
// Walk each subsequent segment
for (int32 i = Start; i < Segments.Num(); i++)
{
FString Key, Value;
if (!Segments[i].Split(TEXT(":"), &Key, &Value))
Key = Segments[i];
bool bFound = false;
for (const FWalker& W : Walkers)
const FWalker* W = GetWalker(Key);
if (!W)
{
if (!StrEq(Key, W.Key)) continue;
(this->*W.Func)(Value);
bFound = true;
break;
}
if (!bFound)
{
SetError(FString::Printf(TEXT("Unknown walker '%s'"), *Key));
SetError(FString::Printf(TEXT("Unknown path step '%s'"), *Key));
return *this;
}
(this->*W->Func)(Value);
if (bError) return *this;
}
return *this;
}
void MCPFetcher::LoadUAsset(const FString& PackagePath)
MCPFetcher& MCPFetcher::Asset(const FString& PackagePath)
{
SetObj(LoadObject<UObject>(nullptr, *PackagePath));
if (!Obj)
@@ -105,6 +91,17 @@ void MCPFetcher::LoadUAsset(const FString& PackagePath)
// If this is a material open in the editor, use the editor's transient copy.
if (UMaterial* Mat = ::Cast<UMaterial>(Obj))
SetObj(MCPUtils::ReplaceMaterialWithTransientCopy(Mat));
return *this;
}
const MCPFetcher::FWalker* MCPFetcher::GetWalker(const FString& Key)
{
for (const FWalker& W : GetWalkerTable())
{
if (StrEq(Key, W.Key))
return &W;
}
return nullptr;
}
MCPFetcher& MCPFetcher::Graph(const FString& Value)

View File

@@ -72,6 +72,7 @@
#include "MaterialGraph/MaterialGraphNode.h"
#include "MaterialGraph/MaterialGraphSchema.h"
#include "IMaterialEditor.h"
#include "MaterialEditingLibrary.h"
#include "Subsystems/AssetEditorSubsystem.h"
// Mesh, animation, texture support
@@ -1125,6 +1126,8 @@ void MCPUtils::PreEdit(const TArray<UObject*>& Objects)
void MCPUtils::PostEdit(const TArray<UObject*>& Objects)
{
TSet<UMaterial*> Materials;
TSet<UBlueprint*> Blueprints;
for (int32 i = Objects.Num() - 1; i >= 0; --i)
{
UObject* Obj = Objects[i];
@@ -1132,8 +1135,36 @@ void MCPUtils::PostEdit(const TArray<UObject*>& Objects)
Obj->MarkPackageDirty();
if (UBlueprint* BP = Cast<UBlueprint>(Obj))
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(BP);
Blueprints.Add(BP);
if (UMaterialInterface* MatIface = Cast<UMaterialInterface>(Obj))
if (UMaterial* BaseMat = MatIface->GetMaterial())
Materials.Add(BaseMat);
}
for (UMaterial *Material : Materials)
UMaterialEditingLibrary::RebuildMaterialInstanceEditors(Material);
for (UBlueprint *Blueprint : Blueprints)
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(Blueprint);
if (GEditor)
GEditor->RedrawAllViewports();
}
TArray<MCPMaterialParameter> MCPUtils::MaterialParameters(UMaterialInstanceConstant *MI)
{
TArray<MCPMaterialParameter> Results;
UMaterial* BaseMat = MI->GetMaterial();
if (!BaseMat) return Results;
for (UMaterialExpression* Expr : BaseMat->GetExpressions())
{
if (!Expr || !Expr->bIsParameterExpression) continue;
MCPMaterialParameter P;
P.Name = Expr->GetParameterName();
if (P.Name.IsNone()) continue;
if (!Expr->GetParameterValue(P.Metadata)) continue;
Results.Add(P);
}
return Results;
}
bool MCPUtils::SaveMaterialPackage(UMaterial* Material)
@@ -1790,6 +1821,19 @@ bool MCPUtils::SetPropertyValueText(UObject* Container, FProperty* Prop, const F
return true;
}
bool MCPUtils::SetPropertyValueText(void* Container, FProperty* Prop, const FString& Value, UObject* Owner, MCPErrorCallback Error)
{
void* ValuePtr = Prop->ContainerPtrToValuePtr<void>(Container);
const TCHAR* ImportResult = Prop->ImportText_Direct(*Value, ValuePtr, Owner, PPF_None);
if (!ImportResult)
{
Error.SetError(FString::Printf(TEXT("Failed to parse '%s' for property '%s' (type: %s)"),
*Value, *FormatName(Prop), *Prop->GetCPPType()));
return false;
}
return true;
}
// ============================================================
// SearchProperties
// ============================================================