I’ve been searching for an answer for changing the TextureParameterValue of a material instance from code but had no luck. So here’s the problem. In my Playercontroller I made this simple code:
TestDesktopPlayerController.h:
UCLASS()
class ATestDesktopPlayerController : public APlayerController
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite, EditAnywhere)
UTexture2D* mCustomTexture;
UPROPERTY(BlueprintReadWrite, EditAnywhere)
UMaterialInstanceDynamic* mCustomMaterial;
ATestDesktopPlayerController();
};
TestDesktopPlayerController.cpp:
ATestDesktopPlayerController::ATestDesktopPlayerController()
{
bShowMouseCursor = true;
bEnableClickEvents = true;
bEnableTouchEvents = true;
DefaultMouseCursor = EMouseCursor::Crosshairs;
int32 width = 40;
int32 height = 40;
TArray<FColor> data;
for (int32 i = 0; i < 1600; i++)
{
data.Add(FColor(0, 0, 255, 255));
}
FCreateTexture2DParameters params;
params.bDeferCompression = false;
params.bSRGB = true;
params.bUseAlpha = true;
params.CompressionSettings = TextureCompressionSettings::TC_Default;
params.SourceGuidHash = FGuid::NewGuid();
mCustomTexture = FImageUtils::CreateTexture2D(width, height, data, this, FString(TEXT("CustomTexture")), EObjectFlags::RF_Public, params);
// Structure to hold one-time initialization
struct FConstructorStatics
{
ConstructorHelpers::FObjectFinderOptional<UMaterialInstanceDynamic> ChildMaterial;
FConstructorStatics() : ChildMaterial(TEXT("Material'/Game/Material/ChildMaterial.ChildMaterial'")){}
};
static FConstructorStatics ConstructorStatics;
if (ConstructorStatics.ChildMaterial.Succeeded())
{
mCustomMaterial = ConstructorStatics.ChildMaterial.Get();
}
if (mCustomMaterial && mCustomTexture)
{
mCustomMaterial->SetTextureParameterValue(FName("Diffuse"), mCustomTexture);
}
}
I made ChildMaterial as material instance from ParentMaterial in UE editor.
Everything seems to be in place and I’ve seen many samples in Answerhub and Forum that use UMaterialInstanceDynamic
, instead of UMaterialInstance
, to manipulate textures. The problem is, UE cannot find my ChildMaterial
material instance if I use ConstructorHelpers::FObjectFinderOptional
with UMaterialInstanceDynamic
as template parameter.
But if I change it to ConstructorHelpers::FObjectFinderOptional
with UMaterialInstance
as template parameter, then it can be found. Is this a bug in UE?
What’s the difference between UMaterialInstance
and UMaterialInstanceDynamic
? When is the perfect time to use each of them?
Because I notice that UMaterialInstanceDynamic
is a subclass of UMaterialInstance
. So why can’t ConstructorHelpers::FObjectFinderOptional
find the asset?