Edit slate material dynamically

Hello everyone…

I have a slate SImage brush which displays a material through FSlateBrush.

The FSlateBrush displays a material. The material has some parameters which I want to edit dynamically. I want to edit them depending on some conditions.

I cant find any variables in FSlateBrush to edit material. So is there a way to edit material per instance of slate SImage widgets or any other Widget to edit materials.

You can do this entirely in BP actually, though you could easily involve C++ as well

in BP, in the Widget

  1. spawn a dynamic material instance after On Construct of the widget

  2. set the SImage to use your dynamically spawned material (“Set Brush From Material”)

  3. now in code or in BP you can modify the dynamic material instance at any time and it will update on the SImage!

Summary:

The core of it all is a UMaterialInstanceDynamic* modified in code or in BP

:slight_smile:

Rama

Sorry for the long bump :stuck_out_tongue:

------Edit---- Fixed



if (HealthBarMaterialBrush.GetResourceObject()->IsA(UMaterialInterface::StaticClass()))
{
		UMaterialInterface* HealthBarMaterial = Cast<UMaterialInterface>(HealthBarMaterialBrush.GetResourceObject());
		HealthBarMaterialD = UMaterialInstanceDynamic::Create(HealthBarMaterial, this);
                HealthBarMaterialBrush.SetResourceObject(HealthBarMaterialD);
		HealthBarMaterialBrush.ImageSize = FVector2D(200, 200);
}


Doing something like this works well…

just in case, I had side effect in non editor version in 4.7 with dynamic material. The material was dropped about 30sec after the first usage (surely garbagged). So test that in standalone game before moving to far with this code ^^

I didn’t find a solution for my issue, I try to talk on it on answerhub without solution as of now. So I move this part in UMG and that solve my problem.

Elvince, you could use the AddToRoot method to prevent the material being garbage out.
F.e.

auto ConstInst = Cast<UMaterialInstanceConstant>(
		FSoftObjectPath("path/to/some/material'").TryLoad());
auto DynamicInst = UMaterialInstanceDynamic::Create(ConstInst, nullptr);
DynamicInst->AddToRoot(); // Prevent the dynamic material being GC

At least, UE5 has this option. I didn’t test this in prev versions.
I hope, this will help anyone :slight_smile: