Working on editing materials
This commit is contained in:
@@ -4,12 +4,12 @@
|
||||
#include "EdGraph/EdGraph.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
#include "EdGraph/EdGraphPin.h"
|
||||
#include "UObject/PropertyAccessUtil.h"
|
||||
#include "Engine/SimpleConstructionScript.h"
|
||||
#include "Engine/SCS_Node.h"
|
||||
#include "Engine/World.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "MaterialGraph/MaterialGraph.h"
|
||||
#include "MaterialGraph/MaterialGraphNode.h"
|
||||
#include "Engine/LevelScriptBlueprint.h"
|
||||
|
||||
MCPFetcher& MCPFetcher::SetError(const FString& Msg)
|
||||
@@ -31,6 +31,19 @@ MCPFetcher& MCPFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expected)
|
||||
return *this;
|
||||
}
|
||||
|
||||
const TArray<MCPFetcher::FWalker>& MCPFetcher::GetWalkerTable()
|
||||
{
|
||||
static const TArray<FWalker> Table = {
|
||||
{ TEXT("graph"), TEXT("Find a named UEdGraph (blank name for material graphs)"), &MCPFetcher::Graph },
|
||||
{ TEXT("node"), TEXT("Find a named UEdGraphNode within a graph or blueprint"), &MCPFetcher::Node },
|
||||
{ TEXT("pin"), TEXT("Find a named UEdGraphPin on a node"), &MCPFetcher::Pin },
|
||||
{ TEXT("component"), TEXT("Find a named component in a Blueprint's SCS"), &MCPFetcher::Component },
|
||||
{ TEXT("levelblueprint"), TEXT("Get the level blueprint from a UWorld"), &MCPFetcher::LevelBlueprint },
|
||||
// { TEXT("matexp"), TEXT("Get the UMaterialExpression from a UMaterialGraphNode"), &MCPFetcher::MatExp },
|
||||
};
|
||||
return Table;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::Walk(const FString& Path)
|
||||
{
|
||||
if (bError) return *this;
|
||||
@@ -53,6 +66,8 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
|
||||
Start = 1;
|
||||
}
|
||||
|
||||
const TArray<FWalker>& Walkers = GetWalkerTable();
|
||||
|
||||
// Walk each subsequent segment
|
||||
for (int32 i = Start; i < Segments.Num(); i++)
|
||||
{
|
||||
@@ -60,13 +75,16 @@ MCPFetcher& MCPFetcher::Walk(const FString& Path)
|
||||
if (!Segments[i].Split(TEXT(":"), &Key, &Value))
|
||||
Key = Segments[i];
|
||||
|
||||
if (StrEq(Key, TEXT("graph"))) Graph(Value);
|
||||
else if (StrEq(Key, TEXT("node"))) Node(Value);
|
||||
else if (StrEq(Key, TEXT("pin"))) Pin(Value);
|
||||
else if (StrEq(Key, TEXT("component"))) Component(Value);
|
||||
else if (StrEq(Key, TEXT("property"))) Property(Value);
|
||||
else if (StrEq(Key, TEXT("levelblueprint"))) LevelBlueprint();
|
||||
else
|
||||
bool bFound = false;
|
||||
for (const FWalker& W : Walkers)
|
||||
{
|
||||
if (!StrEq(Key, W.Key)) continue;
|
||||
(this->*W.Func)(Value);
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
SetError(FString::Printf(TEXT("Unknown walker '%s'"), *Key));
|
||||
return *this;
|
||||
@@ -215,30 +233,7 @@ MCPFetcher& MCPFetcher::Component(const FString& Value)
|
||||
return SetError(FString::Printf(TEXT("Component '%s' not found in %s"), *Value, *BP->GetName()));
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::Property(const FString& Value)
|
||||
{
|
||||
if (bError) return *this;
|
||||
|
||||
if (!Obj)
|
||||
return TypeMismatch(TEXT("property"), TEXT("UObject"));
|
||||
|
||||
FProperty* Prop = Obj->GetClass()->FindPropertyByName(FName(*Value));
|
||||
if (!Prop)
|
||||
return SetError(FString::Printf(TEXT("Property '%s' not found on %s"), *Value, *Obj->GetClass()->GetName()));
|
||||
|
||||
FObjectProperty* ObjProp = CastField<FObjectProperty>(Prop);
|
||||
if (!ObjProp)
|
||||
return SetError(FString::Printf(TEXT("Property '%s' is not an object property (type: %s)"), *Value, *Prop->GetCPPType()));
|
||||
|
||||
UObject* PropValue = ObjProp->GetObjectPropertyValue(Prop->ContainerPtrToValuePtr<void>(Obj));
|
||||
if (!PropValue)
|
||||
return SetError(FString::Printf(TEXT("Property '%s' is null on %s"), *Value, *Obj->GetName()));
|
||||
|
||||
SetObj(PropValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::LevelBlueprint()
|
||||
MCPFetcher& MCPFetcher::LevelBlueprint(const FString& Value)
|
||||
{
|
||||
if (bError) return *this;
|
||||
|
||||
@@ -256,3 +251,36 @@ MCPFetcher& MCPFetcher::LevelBlueprint()
|
||||
SetObj(LevelBP);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::Template()
|
||||
{
|
||||
if (bError) return *this;
|
||||
if (!Obj)
|
||||
return SetError(TEXT("Template: object is null"));
|
||||
|
||||
if (UBlueprint* BP = ::Cast<UBlueprint>(Obj))
|
||||
{
|
||||
if (!BP->GeneratedClass)
|
||||
return SetError(FString::Printf(TEXT("Blueprint '%s' has no GeneratedClass"), *Obj->GetName()));
|
||||
SetObj(BP->GeneratedClass->GetDefaultObject());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Everything else is its own template — no navigation needed.
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPFetcher& MCPFetcher::MatExp(const FString& Value)
|
||||
{
|
||||
if (bError) return *this;
|
||||
|
||||
UMaterialGraphNode* MatNode = ::Cast<UMaterialGraphNode>(Obj);
|
||||
if (!MatNode)
|
||||
return TypeMismatch(TEXT("matexp"), TEXT("UMaterialGraphNode"));
|
||||
|
||||
if (!MatNode->MaterialExpression)
|
||||
return SetError(FString::Printf(TEXT("Node '%s' has no MaterialExpression"), *MCPUtils::FormatName(MatNode)));
|
||||
|
||||
SetObj(MatNode->MaterialExpression);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user