Files
integration/Plugins/BlueprintMCP/Deprecated/Material_ReparentInstance.h
2026-03-13 14:26:04 -04:00

96 lines
2.9 KiB
C++

#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
#include "MCPAssets.h"
#include "MCPUtils.h"
#include "Materials/Material.h"
#include "Materials/MaterialInterface.h"
#include "Materials/MaterialInstanceConstant.h"
#include "Material_ReparentInstance.generated.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
UCLASS()
class UMCP_Material_ReparentInstance : public UObject, public IMCPHandler
{
GENERATED_BODY()
public:
UPROPERTY(meta=(Description="Material Instance name or path to reparent"))
FString MaterialInstance;
UPROPERTY(meta=(Description="New parent material name or path (Material or Material Instance)"))
FString NewParent;
UPROPERTY(meta=(Optional, Description="If true, validate without applying changes"))
bool DryRun = false;
virtual FString GetDescription() const override
{
return TEXT("Change the parent material of a Material Instance. "
"Validates against circular parent chains.");
}
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
{
// Load the Material Instance
MCPAssets<UMaterialInstanceConstant> Assets;
if (!Assets.Exact(MaterialInstance).Errors(Result).ENone().ETwo().Load()) return;
UMaterialInstanceConstant* MI = Assets.Object();
// Load new parent (Material or MaterialInstance)
MCPAssets<UMaterialInterface> ParentAssets;
ParentAssets.NoScans();
ParentAssets.Scan<UMaterial>();
ParentAssets.Scan<UMaterialInstanceConstant>();
if (!ParentAssets.Exact(NewParent).Errors(Result).ENone().ETwo().Load()) return;
UMaterialInterface* NewParentObj = ParentAssets.Object();
// Prevent circular parenting
UMaterialInterface* Check = NewParentObj;
while (Check)
{
if (Check == MI)
{
Result.Appendf(TEXT("ERROR: Reparenting to '%s' would create a circular parent chain.\n"),
*NameOf(NewParentObj));
return;
}
UMaterialInstanceConstant* CheckMI = Cast<UMaterialInstanceConstant>(Check);
if (!CheckMI) break;
Check = CheckMI->Parent;
}
FString OldParentName = MI->Parent ? NameOf(MI->Parent) : TEXT("None");
if (DryRun)
{
Result.Appendf(TEXT("[DRY RUN] Would reparent %s: %s -> %s\n"),
*MCPUtils::FormatName(MI), *OldParentName, *NameOf(NewParentObj));
return;
}
MCPUtils::PreEdit({MI});
MI->Parent = NewParentObj;
MCPUtils::PostEdit({MI});
MCPUtils::SaveGenericPackage(MI);
Result.Appendf(TEXT("Reparented %s: %s -> %s\n"),
*MCPUtils::FormatName(MI), *OldParentName, *NameOf(NewParentObj));
}
private:
FString NameOf(UMaterialInterface* Obj)
{
if (UMaterial* M = Cast<UMaterial>(Obj))
return MCPUtils::FormatName(M);
if (UMaterialInstance* MI = Cast<UMaterialInstance>(Obj))
return MCPUtils::FormatName(MI);
return Obj->GetPathName();
}
};