Using Material for Slate SImage

I am interested in my UI purely using Slate (no UMG).

I am struggling to figure out how to update an SImage in my widget to use a material.

My updateImage function seems to be working because in game I can see the transparent red:

311783-withsetcolorandopacity.png

but when I comment out the "test.SetColorAndOpacity(menuBackgroundRed);"code and then use my “test.SetImage(testController->itemMat);” line I don’t see anything

311784-withsetimagetomat.png

I have the material domain set to User Interface, not sure what I’m missing. The material for now is just black with green lines across it.

311785-materialdomainsettoui.png

//ATestPlayerController.h
class MYPROJECT_API ATestPlayerController : public APlayerController
{
	GENERATED_BODY()
	public:
	UMaterial* itemMat;
...

//ATestPlayerController.cpp
ATestPlayerController::ATestPlayerController()
{
    static ConstructorHelpers::FObjectFinder<UMaterial>itemMaterialAsset(TEXT("Material'/Game/itemIconMaterial'"));
	itemMat = materialAsset.Object;
}


//SItemWidget.h
class MYPROJECT_API SItemWidget : public SCompoundWidget
{
	public:
        SLATE_BEGIN_ARGS(SItemWidget){}
	SLATE_ARGUMENT(TWeakObjectPtr<class ATestHud>, OwningHUD)
    SLATE_END_ARGS()
    void Construct(const FArguments& InArgs);
	SOverlay::FOverlaySlot* slotOverlayItemImage;
...
	
//SItemWidget.cpp
void SItemWidget::Construct(const FArguments& InArgs){
FColor menuBackground{0, 0, 0, 80};
ChildSlot
    .HAlign(HAlign_Left)
    [
        SNew(SCanvas)
        +SCanvas::Slot()
        .Position(FVector2D(20, 500))
        .Size(FVector2D(400, 400))
        .HAlign(HAlign_Left)
        .VAlign(VAlign_Center)
        [
        SNew(SOverlay)
       + SOverlay::Slot()
       .HAlign(HAlign_Fill)
       .VAlign(VAlign_Fill)
       .Expose(slotOverlayItemImage)
       [
           SNew(SImage).ColorAndOpacity(menuBackground)
       ]
...

void SItemWidget::updateImage(){
	FLinearColor menuBackgroundRed{255, 0, 0, 80};
	ATestPlayerController* testController = Cast<ATestPlayerController>(OwningHUD->GetWorld()->GetFirstPlayerController());
	SImage& test = static_cast<SImage&>(slotOverlayItemImage->GetWidget().Get());
    test.SetImage(testController->itemMat);
	//test.SetColorAndOpacity(menuBackgroundRed);
}

I never figured out how to use a material directly for a slate SImage but if I wrapped my material in a slate brush and used the slate brush that worked.

Can u share the code how to use this brush and material Technic

Are able to solve this pls share me the code if u solved it

@dileep343 Currently doing my first steps in Slate (for loading screen purposes in my case), I also did try to use a Material as image along with a Slate Brush. As to your question about examples for using brush with material, here’s some example.
In my case, it is a material with a Flipbook, but it should not matter. So for your question, I hope this is useful for you giving some example, how it can be done. Note, that I’m still fighting issues, see comments at end of the post, but the brush code should be helpful.

The Material:

The Brush struct definitions (I am testing 2 versions, one based on FSlateBrush, the other based on FSlateMaterialBrush)

/**
 * Material Brush based on FSlateBrush for using flipbook texture as
 * alternative to using OnPaint with a sequence of images.
 */
struct FHenryMaterialBrush : public FSlateBrush, public FGCObject
{
	FHenryMaterialBrush(const FName InMaterialName, const FVector2D& InImageSize)
		: FSlateBrush(ESlateBrushDrawType::Image, InMaterialName, FMargin(0), ESlateBrushTileType::NoTile, ESlateBrushImageType::FullColor, InImageSize, FLinearColor(1, 1, 1, 1))
	{
		SetResourceObject(LoadObject<UObject>(NULL, *InMaterialName.ToString()));
	}

	virtual void AddReferencedObjects(FReferenceCollector& Collector)
	{
		if (UObject* CachedResourceObject = GetResourceObject())
		{
			Collector.AddReferencedObject(CachedResourceObject);
		}
	}
};

This second one uses FSlateMaterialBrush as base:

/**
 * Alternative material brush version based on FSlateMaterialBrush
 */
struct FHenryMaterialBrush2 : public FSlateMaterialBrush, public FGCObject
{
	FHenryMaterialBrush2(const FName InMaterialName, const FVector2D& InImageSize)
		: FSlateMaterialBrush(InImageSize)
	{
		SetResourceObject(LoadObject<UObject>(NULL, *InMaterialName.ToString()));
	}

	virtual void AddReferencedObjects(FReferenceCollector& Collector)
	{
		if (UObject* CachedResourceObject = GetResourceObject())
		{
			Collector.AddReferencedObject(CachedResourceObject);
		}
	}
};

Within Construct(), this is handled as follows:

MaterialBrush = MakeShareable(new FHenryMaterialBrush(FName("/Game/Henry/UI/Flipbook-material/M_ChickenFlipbook.M_ChickenFlipbook"), FVector2D(96, 96)));
LoadingMat = SNew(SImage).Image(MaterialBrush.Get());

and

MaterialBrush2 = MakeShareable(new FHenryMaterialBrush2(FName("/Game/Henry/UI/Flipbook-material/M_ChickenFlipbook.M_ChickenFlipbook"), FVector2D(96, 96)));
LoadingMat2 = SNew(SImage).Image(MaterialBrush2.Get());

Add these brushes into the widget.

+ SHorizontalBox::Slot()
....
[
	LoadingMat
]
+ SHorizontalBox::Slot()
....
[
	LoadingMat2
]

It is important to mention:

  • The Material based Brushes do not render at all in my loading screen when preloading at game load. But it does show up when using this widget at in game level switching.
  • While In Game loading, the material itself renders, but the flipbook mechanism does not work - so I only see a single frozen image from my flipbook texture not animating at all. Still investigating this…

@herb64
I had the exact same problem, but I solved it with the function below.
Write it in the constructor.

RegisterActiveTimer( 0.f, FWidgetActiveTimerDelegate::CreateSP( this, &MyWidgetClass::Function ) );