How to Edit Layer Parameters for MaterialInstanceConstant in UE5.5 Using C++

Can you tell me how to config the layers parameter when creating a material instance in C++?

What i need to know is how to add new layer for a MIC, how to assign layer assets and blend assets for the layer, how to assign textures for those layers.

I’d really appreciate it if you could help me.

Steps to Reproduce
I’m developing a plugin that parses customized material files and creates material assets. I’ve prepared a parent material asset with layers, a material layer asset with 4 textures as inputs (color, metalness, normal, roughness), a material blend asset with one mask texture as input. So for each newly-created MaterialInstanceConstant (MIC),I tried to add several layers in layer parameter, and assign the material layer asset and blend asset for each layer, then assign the corresponding textures that are loaded in advance.

[Image Removed]

The material instance from editor is what i’m trying to create in C++.

`FString MaterialLayerPath = TEXT(“/Game/NewMaterialLayer.NewMaterialLayer”);
FString MaterialLayerBlendPath = TEXT(“/Game/NewMaterialLayerBlend.NewMaterialLayerBlend”);
FString LayeredMaterialParent = TEXT(“/Game/NewMaterial.NewMaterial”);
UMaterial* MaterialFather = LoadObject(nullptr, LayeredMaterialParent);
UPackage
Package = CreatePackage(MaterialInstancePackageName);
UMaterialInstanceConstant
NewMIC = NewObject(Package,
UMaterialInstanceConstant::StaticClass(), FName(MaterialInstanceBaseName),
RF_Public | RF_Standalone);
NewMIC->PreEditChange(nullptr);
if (NewMIC != nullptr)
{
NewMIC->Parent = MaterialFather;

FMaterialLayersFunctions LayersValue;
auto& LayersRuntime = LayersValue.GetRuntime();

UMaterialFunctionInterface* BaseLayer = LoadObject(nullptr, MaterialLayerPath);
UMaterialFunctionInterface
BlendLayer = LoadObject(nullptr, *MaterialLayerBlendPath);

LayersRuntime.Blends.Add(BlendLayer);
LayersRuntime.Layers.Add(BaseLayer);
LayersValue.AddDefaultBackgroundLayer();
LayersValue.AppendBlendedLayer();

NewMIC->SetMaterialLayers(LayersValue);

bool bDirty = NewMIC->MarkPackageDirty();
NewMIC->PostEditChange();
FAssetRegistryModule::AssetCreated(NewMIC);
bool bSaveSuccess = UEditorAssetLibrary::SaveAsset(MaterialInstancePackageName, true);
}
StaticMesh->SetMaterial(Index, NewMIC);
}`The first problem is I couldn’t create the MIC by failing some validation during SetMaterialLayer. There must be some data requirement for FMaterialLayersFunction I didn’t realize.

The second problem is I don’t know how to assgin the material layer object and material blend object to the layer parameter, and how to assgin textures to those.

Hi,

Thanks for reaching out. Can you provide some more details on the validation failure from calling SetMaterialLayers?

In the meantime, I found a few UDN threads which may be helpful in your case:

  • [Content removed]
  • [Content removed] (you can translate this to English by right-clicking in Chrome)
  • [Content removed] (the last post in this thread contains a link to a relevant code sample)
  • [Content removed]

Thanks,

Sam

Hi,

thanks for getting back. I’m glad to hear you solved your issue and thank you for providing the solution.

If you have any further questions, just let us know.

Best regards,

Sam

Hi Sam,

Thanks for your kind replay. I just solved the problem 2 days ago. The validation occurs in the function void FMaterialLayersFunctions::Validate(const FMaterialLayersFunctionsRuntimeData& Runtime, const FMaterialLayersFunctionsEditorOnlyData& EditorOnly).

The check condition that stops me is

check(Runtime.Layers.Num() == EditorOnly.LayerStates.Num());

The AppendBlendedLayer function creates new layers in EditorOnly data as well as RunTime data. But I tried to add layers in LayersRuntime at the same time, resulting in inconsistency between EditorOnly Data and Runtime Data.

LayersRuntime.Blends.Add(BlendLayer); LayersRuntime.Layers.Add(BaseLayer); LayersValue.AddDefaultBackgroundLayer(); LayersValue.AppendBlendedLayer(); NewMIC->SetMaterialLayers(LayersValue);This is what works.

LayersValue.AddDefaultBackgroundLayer(); LayersValue.AppendBlendedLayer(); LayersRuntime.Blends[0]=BlendLayer; LayersRuntime.Layers[1]=BaseLayer; NewMIC->SetMaterialLayers(LayersValue);Thanks for your reply and the UDN threads you provided though.

Best,

Roland