Lots of useful work
This commit is contained in:
BIN
Content/Testing/M_Test.uasset
LFS
BIN
Content/Testing/M_Test.uasset
LFS
Binary file not shown.
@@ -5,6 +5,7 @@
|
|||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPAssets.h"
|
#include "MCPAssets.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPTypes.h"
|
||||||
#include "Engine/Blueprint.h"
|
#include "Engine/Blueprint.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
#include "Blueprint_Search.generated.h"
|
#include "Blueprint_Search.generated.h"
|
||||||
@@ -26,12 +27,6 @@ public:
|
|||||||
UPROPERTY(meta=(Optional, Description="Filter by parent class name (exact match, case-insensitive)"))
|
UPROPERTY(meta=(Optional, Description="Filter by parent class name (exact match, case-insensitive)"))
|
||||||
FString ParentClass;
|
FString ParentClass;
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Include regular blueprints (default true)"))
|
|
||||||
bool IncludeRegular = true;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Include level blueprints (default true)"))
|
|
||||||
bool IncludeLevel = true;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
virtual FString GetDescription() const override
|
||||||
{
|
{
|
||||||
return TEXT("List all Blueprint assets in the project, with optional filtering by name, parent class, or type.");
|
return TEXT("List all Blueprint assets in the project, with optional filtering by name, parent class, or type.");
|
||||||
@@ -40,22 +35,21 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPAssets<UObject> Assets;
|
MCPAssets<UObject> Assets;
|
||||||
Assets.NoScans().Substring(Query).Limit(500);
|
Assets.Scan<UBlueprint>().Substring(Query).Limit(500);
|
||||||
if (IncludeRegular) Assets.Scan<UBlueprint>();
|
if (!Assets.Info()) return;
|
||||||
if (IncludeLevel) Assets.Scan<UWorld>();
|
|
||||||
Assets.Info();
|
UClass *Parent = nullptr;
|
||||||
|
if (!ParentClass.IsEmpty())
|
||||||
|
{
|
||||||
|
Parent = UMCPTypes::TextToOneObjectType(ParentClass);
|
||||||
|
if (!Parent) return;
|
||||||
|
}
|
||||||
|
|
||||||
int32 Count = 0;
|
int32 Count = 0;
|
||||||
for (const FAssetData& Asset : Assets.AllData())
|
for (const FAssetData& Asset : Assets.AllData())
|
||||||
{
|
{
|
||||||
// Extract parent class name from asset tags
|
// Extract parent class name from asset tags
|
||||||
FString ParentClassName;
|
FString ParentClassName;
|
||||||
if (Asset.AssetClassPath == UWorld::StaticClass()->GetClassPathName())
|
|
||||||
{
|
|
||||||
ParentClassName = TEXT("LevelScriptActor");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Asset.GetTagValue(FName(TEXT("ParentClass")), ParentClassName);
|
Asset.GetTagValue(FName(TEXT("ParentClass")), ParentClassName);
|
||||||
int32 DotIndex;
|
int32 DotIndex;
|
||||||
if (ParentClassName.FindLastChar('.', DotIndex))
|
if (ParentClassName.FindLastChar('.', DotIndex))
|
||||||
@@ -63,7 +57,6 @@ public:
|
|||||||
ParentClassName = ParentClassName.Mid(DotIndex + 1);
|
ParentClassName = ParentClassName.Mid(DotIndex + 1);
|
||||||
}
|
}
|
||||||
ParentClassName.RemoveFromEnd(TEXT("'"));
|
ParentClassName.RemoveFromEnd(TEXT("'"));
|
||||||
}
|
|
||||||
|
|
||||||
// Apply parent class filter
|
// Apply parent class filter
|
||||||
if (!ParentClass.IsEmpty())
|
if (!ParentClass.IsEmpty())
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "MCPServer.h"
|
|
||||||
#include "MCPHandler.h"
|
|
||||||
#include "MCPUtils.h"
|
|
||||||
#include "Materials/Material.h"
|
|
||||||
#include "MaterialDomain.h"
|
|
||||||
#include "Factories/MaterialFactoryNew.h"
|
|
||||||
#include "MCPPackageMaker.h"
|
|
||||||
#include "Material_Create.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UMCP_Material_Create : public UObject, public IMCPHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Full asset path for the new material (e.g. '/Game/Materials/M_Gold')"))
|
|
||||||
FString AssetPath;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Material domain: Surface, DeferredDecal, LightFunction, Volume, PostProcess, UI"))
|
|
||||||
FString Domain;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Blend mode: Opaque, Masked, Translucent, Additive, Modulate"))
|
|
||||||
FString BlendMode;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Optional, Description="Whether the material is two-sided"))
|
|
||||||
bool TwoSided = false;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Create a new UMaterial asset with optional domain, blend mode, and two-sided settings.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
MCPPackageMaker Maker(AssetPath);
|
|
||||||
if (!Maker.Ok()) return;
|
|
||||||
|
|
||||||
// Parse optional enum properties before creating the asset.
|
|
||||||
EMaterialDomain ParsedDomain = MD_Surface;
|
|
||||||
if (!Domain.IsEmpty())
|
|
||||||
{
|
|
||||||
if (!MCPUtils::StringToEnum(Domain, ParsedDomain, TEXT("MD_")))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EBlendMode ParsedBlendMode = BLEND_Opaque;
|
|
||||||
if (!BlendMode.IsEmpty())
|
|
||||||
{
|
|
||||||
if (!MCPUtils::StringToEnum(BlendMode, ParsedBlendMode, TEXT("BLEND_")))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create via IAssetTools + factory.
|
|
||||||
UMaterial* MaterialObj = Maker.CreateAsset<UMaterial, UMaterialFactoryNew>();
|
|
||||||
if (!MaterialObj) return;
|
|
||||||
|
|
||||||
// Apply optional properties.
|
|
||||||
if (!Domain.IsEmpty())
|
|
||||||
MaterialObj->MaterialDomain = ParsedDomain;
|
|
||||||
|
|
||||||
if (!BlendMode.IsEmpty())
|
|
||||||
MaterialObj->BlendMode = ParsedBlendMode;
|
|
||||||
|
|
||||||
MaterialObj->TwoSided = TwoSided ? 1 : 0;
|
|
||||||
|
|
||||||
bool bSaved = MCPUtils::SaveGenericPackage(MaterialObj);
|
|
||||||
|
|
||||||
UMCPServer::Printf(TEXT("Created %s\n"), *MaterialObj->GetPathName());
|
|
||||||
UMCPServer::Printf(TEXT("Domain: %s\n"), *MCPUtils::EnumToString(MaterialObj->MaterialDomain, TEXT("MD_")));
|
|
||||||
UMCPServer::Printf(TEXT("BlendMode: %s\n"), *MCPUtils::EnumToString(MaterialObj->BlendMode, TEXT("BLEND_")));
|
|
||||||
UMCPServer::Printf(TEXT("TwoSided: %s\n"), MaterialObj->TwoSided ? TEXT("true") : TEXT("false"));
|
|
||||||
if (!bSaved)
|
|
||||||
UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -42,7 +42,7 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPFetcher F;
|
MCPFetcher F;
|
||||||
UBlueprint* BP = F.Walk(Blueprint).ToBlueprint().Cast<UBlueprint>();
|
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||||
if (!BP) return;
|
if (!BP) return;
|
||||||
|
|
||||||
// Check for duplicate variable name
|
// Check for duplicate variable name
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPFetcher F;
|
MCPFetcher F;
|
||||||
UBlueprint* BP = F.Walk(Blueprint).ToBlueprint().Cast<UBlueprint>();
|
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||||
if (!BP) return;
|
if (!BP) return;
|
||||||
|
|
||||||
FBPVarEditor Editor(BP, Variable);
|
FBPVarEditor Editor(BP, Variable);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPFetcher F;
|
MCPFetcher F;
|
||||||
UBlueprint* BP = F.Walk(Blueprint).ToBlueprint().Cast<UBlueprint>();
|
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||||
if (!BP) return;
|
if (!BP) return;
|
||||||
|
|
||||||
FBPVarEditor Editor(BP, Variable);
|
FBPVarEditor Editor(BP, Variable);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPFetcher F;
|
MCPFetcher F;
|
||||||
UBlueprint* BP = F.Walk(Blueprint).ToBlueprint().Cast<UBlueprint>();
|
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||||
if (!BP) return;
|
if (!BP) return;
|
||||||
|
|
||||||
FBPVarEditor Editor(BP, Variable);
|
FBPVarEditor Editor(BP, Variable);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "MCPToolMenu.h"
|
#include "MCPToolMenu.h"
|
||||||
#include "MCPServer.h"
|
#include "MCPServer.h"
|
||||||
#include "ToolMenus.h"
|
#include "ToolMenus.h"
|
||||||
|
#include "MaterialGraph/MaterialGraphNode.h"
|
||||||
#include "GraphNode_ShowMenu.generated.h"
|
#include "GraphNode_ShowMenu.generated.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -34,6 +35,11 @@ private:
|
|||||||
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>();
|
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>();
|
||||||
if (!NodeObj) return;
|
if (!NodeObj) return;
|
||||||
|
|
||||||
|
if (Cast<UMaterialGraphNode>(NodeObj))
|
||||||
|
{
|
||||||
|
UMCPServer::Printf(TEXT("Material graph nodes do not have usable context menus."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
FToolMenuContext Context;
|
FToolMenuContext Context;
|
||||||
TArray<FToolMenuEntry> Entries = MCPToolMenu::GetMenuItems(NodeObj, Context);
|
TArray<FToolMenuEntry> Entries = MCPToolMenu::GetMenuItems(NodeObj, Context);
|
||||||
for (FToolMenuEntry &Entry : Entries)
|
for (FToolMenuEntry &Entry : Entries)
|
||||||
@@ -41,5 +47,6 @@ private:
|
|||||||
FString LabelText = Entry.Label.Get().ToString();
|
FString LabelText = Entry.Label.Get().ToString();
|
||||||
UMCPServer::Printf(TEXT("%s\n"), *LabelText);
|
UMCPServer::Printf(TEXT("%s\n"), *LabelText);
|
||||||
}
|
}
|
||||||
|
if (Entries.IsEmpty()) UMCPServer::Printf(TEXT("No selectable menu entries right now.\n"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPFetcher F;
|
MCPFetcher F;
|
||||||
UEdGraph* G = F.Walk(Graph).ToGraph().Cast<UEdGraph>();
|
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
||||||
if (!G) return;
|
if (!G) return;
|
||||||
|
|
||||||
int32 SuccessCount = 0;
|
int32 SuccessCount = 0;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPFetcher F;
|
MCPFetcher F;
|
||||||
UEdGraph* G = F.Walk(Graph).ToGraph().Cast<UEdGraph>();
|
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>();
|
||||||
if (!G) return;
|
if (!G) return;
|
||||||
|
|
||||||
int32 SuccessCount = 0;
|
int32 SuccessCount = 0;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public:
|
|||||||
virtual void Handle() override
|
virtual void Handle() override
|
||||||
{
|
{
|
||||||
MCPFetcher F;
|
MCPFetcher F;
|
||||||
UEdGraph *G = F.Walk(Graph).ToGraph().Cast<UEdGraph>();
|
UEdGraph *G = F.Walk(Graph).Cast<UEdGraph>();
|
||||||
if (!G) return;
|
if (!G) return;
|
||||||
|
|
||||||
MCPGraphExport Exporter(G);
|
MCPGraphExport Exporter(G);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MaterialParameter.h"
|
||||||
#include "Materials/MaterialInstanceConstant.h"
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "MaterialInstance_ClearParameter.generated.h"
|
#include "MaterialInstance_ClearParameter.generated.h"
|
||||||
@@ -45,7 +46,7 @@ public:
|
|||||||
|
|
||||||
// Parse the association string.
|
// Parse the association string.
|
||||||
EMaterialParameterAssociation Association;
|
EMaterialParameterAssociation Association;
|
||||||
if (!MCPUtils::ParseMaterialParameterAssociation(ParameterAssociation, Association))
|
if (!MCPMaterialParameter::ParseMaterialParameterAssociation(ParameterAssociation, Association))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
|
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MaterialParameter.h"
|
||||||
#include "Materials/MaterialInstanceConstant.h"
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "MaterialInstance_DumpParameters.generated.h"
|
#include "MaterialInstance_DumpParameters.generated.h"
|
||||||
@@ -34,7 +35,7 @@ public:
|
|||||||
UMaterialInstanceConstant* MI = F.Asset(MaterialInstance).Cast<UMaterialInstanceConstant>();
|
UMaterialInstanceConstant* MI = F.Asset(MaterialInstance).Cast<UMaterialInstanceConstant>();
|
||||||
if (!MI) return;
|
if (!MI) return;
|
||||||
|
|
||||||
auto AllParams = MCPUtils::GetMaterialParameters(MI);
|
auto AllParams = MCPMaterialParameter::GetMaterialParameters(MI);
|
||||||
|
|
||||||
// Overridden parameters first.
|
// Overridden parameters first.
|
||||||
bool bHasOverrides = false;
|
bool bHasOverrides = false;
|
||||||
@@ -42,7 +43,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (!Meta.bOverride) continue;
|
if (!Meta.bOverride) continue;
|
||||||
if (!bHasOverrides) { UMCPServer::Print(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
|
if (!bHasOverrides) { UMCPServer::Print(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
|
||||||
MCPUtils::FormatMaterialParameter(Info, Meta);
|
MCPMaterialParameter::FormatMaterialParameter(Info, Meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inherited (non-overridden) parameters.
|
// Inherited (non-overridden) parameters.
|
||||||
@@ -51,7 +52,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (Meta.bOverride) continue;
|
if (Meta.bOverride) continue;
|
||||||
if (!bHasInherited) { UMCPServer::Print(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
|
if (!bHasInherited) { UMCPServer::Print(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
|
||||||
MCPUtils::FormatMaterialParameter(Info, Meta);
|
MCPMaterialParameter::FormatMaterialParameter(Info, Meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
|
#include "MaterialParameter.h"
|
||||||
#include "Materials/MaterialInstanceConstant.h"
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "Misc/DefaultValueHelper.h"
|
#include "Misc/DefaultValueHelper.h"
|
||||||
@@ -49,14 +50,14 @@ public:
|
|||||||
|
|
||||||
// Parse the association string.
|
// Parse the association string.
|
||||||
EMaterialParameterAssociation Association;
|
EMaterialParameterAssociation Association;
|
||||||
if (!MCPUtils::ParseMaterialParameterAssociation(ParameterAssociation, Association))
|
if (!MCPMaterialParameter::ParseMaterialParameterAssociation(ParameterAssociation, Association))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Build the parameter ID to look up.
|
// Build the parameter ID to look up.
|
||||||
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
|
FMaterialParameterInfo ParamID(*Parameter, Association, ParameterLayer);
|
||||||
|
|
||||||
// Find it in the material's parameter map.
|
// Find it in the material's parameter map.
|
||||||
auto AllParams = MCPUtils::GetMaterialParameters(MI);
|
auto AllParams = MCPMaterialParameter::GetMaterialParameters(MI);
|
||||||
FMaterialParameterMetadata* Found = AllParams.Find(ParamID);
|
FMaterialParameterMetadata* Found = AllParams.Find(ParamID);
|
||||||
if (!Found)
|
if (!Found)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
|
#include "MCPHandler.h"
|
||||||
|
#include "MCPUtils.h"
|
||||||
|
#include "Materials/Material.h"
|
||||||
|
#include "MaterialDomain.h"
|
||||||
|
#include "Factories/MaterialFactoryNew.h"
|
||||||
|
#include "MCPPackageMaker.h"
|
||||||
|
#include "Material_Create.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UMCP_Material_Create : public UObject, public IMCPHandler
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(meta=(Description="Full asset path for the new material"))
|
||||||
|
FString Material;
|
||||||
|
|
||||||
|
virtual FString GetDescription() const override
|
||||||
|
{
|
||||||
|
return TEXT("Create a new UMaterial asset");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Handle() override
|
||||||
|
{
|
||||||
|
MCPPackageMaker Maker(Material);
|
||||||
|
if (!Maker.Ok()) return;
|
||||||
|
|
||||||
|
// Create via IAssetTools + factory.
|
||||||
|
UMaterial* MaterialObj = Maker.CreateAsset<UMaterial, UMaterialFactoryNew>();
|
||||||
|
if (!MaterialObj) return;
|
||||||
|
|
||||||
|
bool bSaved = MCPUtils::SaveGenericPackage(MaterialObj);
|
||||||
|
UMCPServer::Printf(TEXT("Created %s\n"), *MaterialObj->GetPathName());
|
||||||
|
if (!bSaved) UMCPServer::Print(TEXT("WARNING: Package save failed\n"));
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -3,8 +3,9 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "MCPHandler.h"
|
#include "MCPHandler.h"
|
||||||
#include "MCPFetcher.h"
|
#include "MCPFetcher.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
#include "MCPUtils.h"
|
#include "MCPUtils.h"
|
||||||
#include "Materials/Material.h"
|
#include "MaterialParameter.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "Material_DumpParameters.generated.h"
|
#include "Material_DumpParameters.generated.h"
|
||||||
|
|
||||||
@@ -33,11 +34,12 @@ public:
|
|||||||
UMaterial* Mat = F.Asset(Material).Cast<UMaterial>();
|
UMaterial* Mat = F.Asset(Material).Cast<UMaterial>();
|
||||||
if (!Mat) return;
|
if (!Mat) return;
|
||||||
|
|
||||||
auto AllParams = MCPUtils::GetMaterialParameters(Mat);
|
auto AllParams = MCPMaterialParameter::GetMaterialParameters(Mat);
|
||||||
|
|
||||||
for (auto& [Info, Meta] : AllParams)
|
for (auto& [Info, Meta] : AllParams)
|
||||||
{
|
{
|
||||||
MCPUtils::FormatMaterialParameter(Info, Meta);
|
MCPMaterialParameter::FormatMaterialParameter(Info, Meta);
|
||||||
}
|
}
|
||||||
|
if (AllParams.IsEmpty()) UMCPServer::Printf(TEXT("No material parameters.\n"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -78,8 +78,8 @@ public:
|
|||||||
{
|
{
|
||||||
UMCPServer::Printf(TEXT("\n"));
|
UMCPServer::Printf(TEXT("\n"));
|
||||||
EmitCommandList(false);
|
EmitCommandList(false);
|
||||||
UMCPServer::Print(TEXT("\n--- Half-Baked (may have issues) ---\n\n"));
|
// UMCPServer::Print(TEXT("\n--- Half-Baked (may have issues) ---\n\n"));
|
||||||
EmitCommandList(true);
|
// EmitCommandList(true);
|
||||||
UMCPServer::Printf(TEXT("\n"));
|
UMCPServer::Printf(TEXT("\n"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,12 +35,10 @@ public:
|
|||||||
"\n component — move from a blueprint to a component"
|
"\n component — move from a blueprint to a component"
|
||||||
"\n levelblueprint — move from a world to a blueprint"
|
"\n levelblueprint — move from a world to a blueprint"
|
||||||
"\n"
|
"\n"
|
||||||
"\n DUMP COMMANDS:"
|
"\n Steps do not always require a parameter. For example, materials"
|
||||||
|
"\n only have one graph, so you can just say:"
|
||||||
"\n"
|
"\n"
|
||||||
"\n There are several commands whose names end in 'Dump'. These"
|
"\n /Game/Materials/MyMaterial,graph"
|
||||||
"\n are essential tools for viewing the state of the world."
|
|
||||||
"\n They are particularly important because they show you what"
|
|
||||||
"\n unique IDs exist that you can refer to."
|
|
||||||
"\n"
|
"\n"
|
||||||
"\n TYPES:"
|
"\n TYPES:"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -80,6 +78,12 @@ public:
|
|||||||
"\n properties, which actually come from the material expressions."
|
"\n properties, which actually come from the material expressions."
|
||||||
"\n You can edit these using Property_Set on the node."
|
"\n You can edit these using Property_Set on the node."
|
||||||
"\n"
|
"\n"
|
||||||
|
"\n COMMANDS YOU SHOULD KNOW ABOUT AND REMEMBER:"
|
||||||
|
"\n"
|
||||||
|
"\n UserManual: this explanation"
|
||||||
|
"\n ShowCommands: a full list of all the commands"
|
||||||
|
"\n Graph_Dump: a detailed listing of any UEdGraph"
|
||||||
|
"\n Property_Dump: show information on many objects"
|
||||||
"\n"
|
"\n"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ MCPFetcher::WalkFunc MCPFetcher::GetWalker(const FString& Step)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MCPFetcher::SetObj(UObject* InObj)
|
void MCPFetcher::SetObj(UObject* InObj)
|
||||||
{
|
{
|
||||||
UMCPServer::AddTouchedObject(InObj);
|
UMCPServer::AddTouchedObject(InObj);
|
||||||
@@ -49,15 +48,26 @@ MCPFetcher& MCPFetcher::SetError()
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCPFetcher::PathFailed(const TCHAR* Expected)
|
||||||
|
{
|
||||||
|
SetError();
|
||||||
|
if (ResultPin)
|
||||||
|
UMCPServer::Printf(TEXT("ERROR: Path specifies a pin, but expected %s\n"), Expected);
|
||||||
|
else if (Obj)
|
||||||
|
UMCPServer::Printf(TEXT("ERROR: Path specifies a %s, but expected %s\n"), *Obj->GetClass()->GetName(), Expected);
|
||||||
|
else
|
||||||
|
UMCPServer::Printf(TEXT("ERROR: Path led to a null pointer\n"));
|
||||||
|
}
|
||||||
|
|
||||||
MCPFetcher& MCPFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expected)
|
MCPFetcher& MCPFetcher::TypeMismatch(const TCHAR* Walker, const TCHAR* Expected)
|
||||||
{
|
{
|
||||||
bError = true;
|
SetError();
|
||||||
if (ResultPin)
|
if (ResultPin)
|
||||||
UMCPServer::Printf(TEXT("ERROR: Input to '%s' is a pin, expected %s\n"), Walker, Expected);
|
UMCPServer::Printf(TEXT("ERROR: Input to '%s' is a pin, but expected %s\n"), Walker, Expected);
|
||||||
else if (Obj)
|
else if (Obj)
|
||||||
UMCPServer::Printf(TEXT("ERROR: Input to '%s' is %s, expected %s\n"), Walker, *Obj->GetClass()->GetName(), Expected);
|
UMCPServer::Printf(TEXT("ERROR: Input to '%s' is %s, but expected %s\n"), Walker, *Obj->GetClass()->GetName(), Expected);
|
||||||
else
|
else
|
||||||
UMCPServer::Printf(TEXT("ERROR: Input to '%s' is null, expected %s\n"), Walker, Expected);
|
UMCPServer::Printf(TEXT("ERROR: Path led to a null pointer\n"));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,47 +344,3 @@ MCPFetcher& MCPFetcher::LevelBlueprint(const FString& Value)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCPFetcher& MCPFetcher::ToBlueprint()
|
|
||||||
{
|
|
||||||
if (bError) return *this;
|
|
||||||
if (::Cast<UBlueprint>(Obj)) return *this;
|
|
||||||
|
|
||||||
if (UWorld* World = ::Cast<UWorld>(Obj))
|
|
||||||
{
|
|
||||||
if (!World->PersistentLevel)
|
|
||||||
{
|
|
||||||
UMCPServer::Print(TEXT("ERROR: ToBlueprint: World has no PersistentLevel\n"));
|
|
||||||
return SetError();
|
|
||||||
}
|
|
||||||
ULevelScriptBlueprint* LevelBP = World->PersistentLevel->GetLevelScriptBlueprint(true);
|
|
||||||
if (!LevelBP)
|
|
||||||
{
|
|
||||||
UMCPServer::Print(TEXT("ERROR: ToBlueprint: World has no level blueprint\n"));
|
|
||||||
return SetError();
|
|
||||||
}
|
|
||||||
SetObj(LevelBP);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TypeMismatch(TEXT("ToBlueprint"), TEXT("Blueprint or World"));
|
|
||||||
}
|
|
||||||
|
|
||||||
MCPFetcher& MCPFetcher::ToGraph()
|
|
||||||
{
|
|
||||||
if (bError) return *this;
|
|
||||||
if (::Cast<UEdGraph>(Obj)) return *this;
|
|
||||||
|
|
||||||
if (UMaterial* Mat = ::Cast<UMaterial>(Obj))
|
|
||||||
{
|
|
||||||
MCPUtils::EnsureMaterialGraph(Mat);
|
|
||||||
if (!Mat->MaterialGraph)
|
|
||||||
{
|
|
||||||
UMCPServer::Printf(TEXT("ERROR: ToGraph: Material '%s' has no material graph\n"), *Mat->GetName());
|
|
||||||
return SetError();
|
|
||||||
}
|
|
||||||
SetObj(Mat->MaterialGraph);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TypeMismatch(TEXT("ToGraph"), TEXT("Graph or Material"));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -423,9 +423,6 @@ void UMCPServer::ClientThreadFunc(UMCPServer* Server, TSharedPtr<FClientConnecti
|
|||||||
// Block until the game thread processes this message
|
// Block until the game thread processes this message
|
||||||
FString Response = Future.Get();
|
FString Response = Future.Get();
|
||||||
|
|
||||||
// Empty response means either notification or shutdown
|
|
||||||
if (Response.IsEmpty()) continue;
|
|
||||||
|
|
||||||
// Write the response back, null-terminated (blocking)
|
// Write the response back, null-terminated (blocking)
|
||||||
FTCHARToUTF8 Utf8(*Response);
|
FTCHARToUTF8 Utf8(*Response);
|
||||||
int32 BytesSent = 0;
|
int32 BytesSent = 0;
|
||||||
|
|||||||
@@ -514,81 +514,6 @@ UMaterial* MCPUtils::ReplaceMaterialWithTransientCopy(UMaterial* Material)
|
|||||||
return Material;
|
return Material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> MCPUtils::GetMaterialParameters(UMaterialInterface* Material)
|
|
||||||
{
|
|
||||||
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> Result;
|
|
||||||
if (!Material) return Result;
|
|
||||||
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> Temp;
|
|
||||||
for (int32 i = 0; i < (int32)EMaterialParameterType::NumRuntime; i++)
|
|
||||||
{
|
|
||||||
Material->GetAllParametersOfType((EMaterialParameterType)i, Temp);
|
|
||||||
Result.Append(Temp);
|
|
||||||
}
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MCPUtils::ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation)
|
|
||||||
{
|
|
||||||
if (Str.Equals(TEXT("Global"), ESearchCase::IgnoreCase))
|
|
||||||
OutAssociation = GlobalParameter;
|
|
||||||
else if (Str.Equals(TEXT("Layer"), ESearchCase::IgnoreCase))
|
|
||||||
OutAssociation = LayerParameter;
|
|
||||||
else if (Str.Equals(TEXT("Blend"), ESearchCase::IgnoreCase))
|
|
||||||
OutAssociation = BlendParameter;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UMCPServer::Printf(TEXT("ERROR: Invalid ParameterAssociation '%s' (expected 'Global', 'Layer', or 'Blend')\n"), *Str);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MCPUtils::FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
|
|
||||||
{
|
|
||||||
// Association prefix for layer/blend parameters.
|
|
||||||
FString Prefix;
|
|
||||||
if (Info.Association == LayerParameter)
|
|
||||||
Prefix = FString::Printf(TEXT("[Layer %d] "), Info.Index);
|
|
||||||
else if (Info.Association == BlendParameter)
|
|
||||||
Prefix = FString::Printf(TEXT("[Blend %d] "), Info.Index);
|
|
||||||
|
|
||||||
switch (Meta.Value.Type)
|
|
||||||
{
|
|
||||||
case EMaterialParameterType::Scalar:
|
|
||||||
UMCPServer::Printf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
|
|
||||||
break;
|
|
||||||
case EMaterialParameterType::Vector:
|
|
||||||
{
|
|
||||||
FLinearColor C = Meta.Value.AsLinearColor();
|
|
||||||
UMCPServer::Printf(TEXT(" %sVector \"%s\" = (R=%.3f, G=%.3f, B=%.3f, A=%.3f)\n"),
|
|
||||||
*Prefix, *Info.Name.ToString(), C.R, C.G, C.B, C.A);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EMaterialParameterType::DoubleVector:
|
|
||||||
{
|
|
||||||
FVector4d V = Meta.Value.AsVector4d();
|
|
||||||
UMCPServer::Printf(TEXT(" %sDoubleVector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
|
|
||||||
*Prefix, *Info.Name.ToString(), V.X, V.Y, V.Z, V.W);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EMaterialParameterType::Texture:
|
|
||||||
{
|
|
||||||
UTexture* Tex = Cast<UTexture>(Meta.Value.AsTextureObject());
|
|
||||||
UMCPServer::Printf(TEXT(" %sTexture \"%s\" = %s\n"),
|
|
||||||
*Prefix, *Info.Name.ToString(), Tex ? *MCPUtils::FormatName(Tex) : TEXT("None"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EMaterialParameterType::StaticSwitch:
|
|
||||||
UMCPServer::Printf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
|
|
||||||
*Prefix, *Info.Name.ToString(), Meta.Value.AsStaticSwitch() ? TEXT("true") : TEXT("false"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UMCPServer::Printf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MCPUtils::SaveGenericPackage(UObject* Asset)
|
bool MCPUtils::SaveGenericPackage(UObject* Asset)
|
||||||
{
|
{
|
||||||
if (!Asset) return false;
|
if (!Asset) return false;
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#include "MaterialParameter.h"
|
||||||
|
#include "MCPUtils.h"
|
||||||
|
#include "MCPServer.h"
|
||||||
|
|
||||||
|
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> MCPMaterialParameter::GetMaterialParameters(UMaterialInterface* Material)
|
||||||
|
{
|
||||||
|
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> Result;
|
||||||
|
if (!Material) return Result;
|
||||||
|
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> Temp;
|
||||||
|
for (int32 i = 0; i < (int32)EMaterialParameterType::NumRuntime; i++)
|
||||||
|
{
|
||||||
|
Material->GetAllParametersOfType((EMaterialParameterType)i, Temp);
|
||||||
|
Result.Append(Temp);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MCPMaterialParameter::ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation)
|
||||||
|
{
|
||||||
|
if (Str.Equals(TEXT("Global"), ESearchCase::IgnoreCase))
|
||||||
|
OutAssociation = GlobalParameter;
|
||||||
|
else if (Str.Equals(TEXT("Layer"), ESearchCase::IgnoreCase))
|
||||||
|
OutAssociation = LayerParameter;
|
||||||
|
else if (Str.Equals(TEXT("Blend"), ESearchCase::IgnoreCase))
|
||||||
|
OutAssociation = BlendParameter;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UMCPServer::Printf(TEXT("ERROR: Invalid ParameterAssociation '%s' (expected 'Global', 'Layer', or 'Blend')\n"), *Str);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCPMaterialParameter::FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta)
|
||||||
|
{
|
||||||
|
// Association prefix for layer/blend parameters.
|
||||||
|
FString Prefix;
|
||||||
|
if (Info.Association == LayerParameter)
|
||||||
|
Prefix = FString::Printf(TEXT("[Layer %d] "), Info.Index);
|
||||||
|
else if (Info.Association == BlendParameter)
|
||||||
|
Prefix = FString::Printf(TEXT("[Blend %d] "), Info.Index);
|
||||||
|
|
||||||
|
switch (Meta.Value.Type)
|
||||||
|
{
|
||||||
|
case EMaterialParameterType::Scalar:
|
||||||
|
UMCPServer::Printf(TEXT(" %sScalar \"%s\" = %g\n"), *Prefix, *Info.Name.ToString(), Meta.Value.AsScalar());
|
||||||
|
break;
|
||||||
|
case EMaterialParameterType::Vector:
|
||||||
|
{
|
||||||
|
FLinearColor C = Meta.Value.AsLinearColor();
|
||||||
|
UMCPServer::Printf(TEXT(" %sVector \"%s\" = (R=%.3f, G=%.3f, B=%.3f, A=%.3f)\n"),
|
||||||
|
*Prefix, *Info.Name.ToString(), C.R, C.G, C.B, C.A);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EMaterialParameterType::DoubleVector:
|
||||||
|
{
|
||||||
|
FVector4d V = Meta.Value.AsVector4d();
|
||||||
|
UMCPServer::Printf(TEXT(" %sDoubleVector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
|
||||||
|
*Prefix, *Info.Name.ToString(), V.X, V.Y, V.Z, V.W);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EMaterialParameterType::Texture:
|
||||||
|
{
|
||||||
|
UTexture* Tex = Cast<UTexture>(Meta.Value.AsTextureObject());
|
||||||
|
UMCPServer::Printf(TEXT(" %sTexture \"%s\" = %s\n"),
|
||||||
|
*Prefix, *Info.Name.ToString(), Tex ? *MCPUtils::FormatName(Tex) : TEXT("None"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EMaterialParameterType::StaticSwitch:
|
||||||
|
UMCPServer::Printf(TEXT(" %sStaticSwitch \"%s\" = %s\n"),
|
||||||
|
*Prefix, *Info.Name.ToString(), Meta.Value.AsStaticSwitch() ? TEXT("true") : TEXT("false"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UMCPServer::Printf(TEXT(" %sType%d \"%s\"\n"), *Prefix, (int)Meta.Value.Type, *Info.Name.ToString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -54,15 +54,6 @@ public:
|
|||||||
MCPFetcher& Component(const FString& Value);
|
MCPFetcher& Component(const FString& Value);
|
||||||
MCPFetcher& LevelBlueprint(const FString& Value);
|
MCPFetcher& LevelBlueprint(const FString& Value);
|
||||||
|
|
||||||
// The following walkers cannot be invoked from
|
|
||||||
// paths, only procedurally. If the current object
|
|
||||||
// is already the target type, they do nothing.
|
|
||||||
// Otherwise, they attempt to convert (e.g. World
|
|
||||||
// to its level blueprint, Material to its graph).
|
|
||||||
//
|
|
||||||
MCPFetcher& ToBlueprint();
|
|
||||||
MCPFetcher& ToGraph();
|
|
||||||
|
|
||||||
// Return true if there haven't been any errors.
|
// Return true if there haven't been any errors.
|
||||||
// Note that errors always automatically generate
|
// Note that errors always automatically generate
|
||||||
// output to MCPServer::Printf.
|
// output to MCPServer::Printf.
|
||||||
@@ -77,8 +68,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (bError) return nullptr;
|
if (bError) return nullptr;
|
||||||
T* Result = ::Cast<T>(Obj);
|
T* Result = ::Cast<T>(Obj);
|
||||||
if (Result == nullptr)
|
if (Result == nullptr) PathFailed(*T::StaticClass()->GetName());
|
||||||
TypeMismatch(TEXT("Cast"), *T::StaticClass()->GetName());
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +134,7 @@ private:
|
|||||||
void SetObj(UObject* InObj);
|
void SetObj(UObject* InObj);
|
||||||
void SetPin(UEdGraphPin* InPin);
|
void SetPin(UEdGraphPin* InPin);
|
||||||
MCPFetcher& SetError();
|
MCPFetcher& SetError();
|
||||||
|
void PathFailed(const TCHAR *Kind);
|
||||||
MCPFetcher& TypeMismatch(const TCHAR* Walker, const TCHAR* Expected);
|
MCPFetcher& TypeMismatch(const TCHAR* Walker, const TCHAR* Expected);
|
||||||
bool CheckAssetIsA(UClass* StaticClass);
|
bool CheckAssetIsA(UClass* StaticClass);
|
||||||
WalkFunc GetWalker(const FString &Step);
|
WalkFunc GetWalker(const FString &Step);
|
||||||
@@ -152,7 +143,6 @@ private:
|
|||||||
template<> inline UEdGraphPin* MCPFetcher::Cast<UEdGraphPin>()
|
template<> inline UEdGraphPin* MCPFetcher::Cast<UEdGraphPin>()
|
||||||
{
|
{
|
||||||
if (bError) return nullptr;
|
if (bError) return nullptr;
|
||||||
if (!ResultPin)
|
if (!ResultPin) PathFailed(TEXT("UEdGraphPin"));
|
||||||
TypeMismatch(TEXT("Cast"), TEXT("pin"));
|
|
||||||
return ResultPin;
|
return ResultPin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,11 +153,6 @@ public:
|
|||||||
static FString ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action);
|
static FString ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action);
|
||||||
static TArray<TSharedPtr<FEdGraphSchemaAction>> SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults = 0, bool ExactMatch = false);
|
static TArray<TSharedPtr<FEdGraphSchemaAction>> SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults = 0, bool ExactMatch = false);
|
||||||
|
|
||||||
// ----- Material Parameters -----
|
|
||||||
static TMap<FMaterialParameterInfo, FMaterialParameterMetadata> GetMaterialParameters(UMaterialInterface* Material);
|
|
||||||
static bool ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation);
|
|
||||||
static void FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta);
|
|
||||||
|
|
||||||
// ----- Editable template -----
|
// ----- Editable template -----
|
||||||
static TArray<FProperty*> SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal);
|
static TArray<FProperty*> SearchProperties(UObject* Obj, const FString& Query, EPropertyFlags Flags, bool bLocal);
|
||||||
static FProperty* FindPropertyByName(UObject* Obj, const FString& Name);
|
static FProperty* FindPropertyByName(UObject* Obj, const FString& Name);
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Materials/Material.h"
|
||||||
|
|
||||||
|
class MCPMaterialParameter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static TMap<FMaterialParameterInfo, FMaterialParameterMetadata> GetMaterialParameters(UMaterialInterface* Material);
|
||||||
|
static bool ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation);
|
||||||
|
static void FormatMaterialParameter(const FMaterialParameterInfo& Info, const FMaterialParameterMetadata& Meta);
|
||||||
|
};
|
||||||
|
|
||||||
@@ -20,7 +20,6 @@ TOOL_DESCRIPTION = (
|
|||||||
"Send a command to the Unreal Editor's BlueprintMCP plugin. "
|
"Send a command to the Unreal Editor's BlueprintMCP plugin. "
|
||||||
"The 'command' field specifies which operation to perform; "
|
"The 'command' field specifies which operation to perform; "
|
||||||
"additional fields are command-specific parameters. "
|
"additional fields are command-specific parameters. "
|
||||||
'Use {"command": "ShowCommands"} to list available commands. '
|
|
||||||
'Use {"command": "UserManual"} to get an overview. '
|
'Use {"command": "UserManual"} to get an overview. '
|
||||||
"If the editor is not running, the call will return an error; "
|
"If the editor is not running, the call will return an error; "
|
||||||
"just ask the user to start the editor and try again."
|
"just ask the user to start the editor and try again."
|
||||||
|
|||||||
Reference in New Issue
Block a user