How to set a texture parameter in C++?

I’m working on a custom USceneComponent. In the constructor I’m trying to load a material asset, a texture asset and apply the material to an attached static mesh component.

This is what I have so far:

Mesh = ObjectInitializer.CreateDefaultSubobject<USquareMeshComponent>(this, TEXT("Mesh"));
Mesh->AttachParent = this;

static ConstructorHelpers::FObjectFinder<UMaterial> MaterialFinder(
    TEXT("Material'/Game/Materials/DynamicTextureMaterial.DynamicTextureMaterial'"));
UMaterial* Material = MaterialFinder.Object;
DynamicMaterial = UMaterialInstanceDynamic::Create(Material, NULL);

static ConstructorHelpers::FObjectFinder<UTexture> TextureFinder(
    TEXT("Texture2D'/Game/Textures/2DBackground.2DBackground'"));
UTexture* Texture = TextureFinder.Object;

DynamicMaterial->SetTextureParameterValue(FName(TEXT("DynamicTexture")), Texture);
Mesh->SetMaterial(0, DynamicMaterial);

This compiles fine, but crashes the Editor on launch, except if I comment the SetTextureParameterValue call. Without it I can start the Editor, see my component, just with the wrong default texture.

I tried doing the same in the Level BP’s Event Play and it worked fine. So my material and texture should be ok.

Am I doing something wrong? Thanks!

Don’t put SetTextureParameerValue and SetMaterial in your Constructor try to move it to PostInitializeComponents

I’m implementing a component, not an actor. As far as I can tell, PostInitializeComponents is a method on AActor. Do you have a suggestion what to do in a component? I tried to move those calls to PostInitProperties with the same results (crash on launch). Thanks!

Okay, so setting the texture and material in the PostLoad method of my component seems to work.

Here is what turned out to work for me.

In my component constructor I load the assets and assign them to my properties:

struct FConstructorStatics
{
	ConstructorHelpers::FObjectFinderOptional<UTexture> TextureFinder;
	ConstructorHelpers::FObjectFinderOptional<UMaterial> MaterialFinder;
	FConstructorStatics()
		: TextureFinder(TEXT("Texture2D'/Game/Textures/2DBackground.2DBackground'"))
		, MaterialFinder(TEXT("Material'/Game/Materials/DynamicTextureMaterial.DynamicTextureMaterial'"))
	{
	}
};
static FConstructorStatics ConstructorStatics;

Texture = ConstructorStatics.TextureFinder.Get();
UMaterial* Material = ConstructorStatics.MaterialFinder.Get();
DynamicMaterial = UMaterialInstanceDynamic::Create(Material, this);

Then in my component’s PostLoad I apply them:

DynamicMaterial->SetTextureParameterValue(FName("DynamicTexture"), Texture);
Mesh->SetMaterial(0, DynamicMaterial);

Thanks Duncan and Rajko for the suggestions!

For me the finder only works inside a AHUD derived class :confused:

Hi Bajee,

The SetTextureParameterValue() function does not exist in UMaterialInstanceDynamic class nor UMaterialInstance class. What UE version did you use?

I’m using version 4.11 and all I see is SetTextureParameterValueInternal() function but it is protected. How did you do this in UE 4.11 and later?

Not sure what you’re talking about, SetTextureParameterValue is definitely a member function of UMaterialInstanceDynamic still…