GetParameterDesc on UMaterialInstanceDynamic

This may be a bug.

The following code fails:

UMaterialInterface* OriginalMaterial;

FString Desc;
bool bHasParameter = OriginalMaterial->GetParameterDesc(TEXT("ParamName"), Desc);

UMaterialInstanceDynamic* MaterialDynamic = UMaterialInstanceDynamic::Create(OriginalMaterial, GetTransientPackage());

check(MaterialDynamic->GetParameterDesc(TEXT("ParamDesc"), Desc);
  1. Create a new blank c++ project.

  2. Create a material with a scalar parameter, name it “Test”. Connect this to metallic.

  3. Create a new actor c++ class. Ensure the header has the following public properties:
    UPROPERTY(EditDefaultsOnly)
    UMaterialInterface* Material;

    UPROPERTY(EditDefaultsOnly)
    UMaterialInstanceDynamic* MaterialInstance;

  4. In BeginPlay of this class, paste the following after Super::BeginPlay():

    if (Material == nullptr)
    return;

    FString Desc;
    if (Material->GetParameterDesc(TEXT(“Test”), Desc))
    GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::, TEXT(“Material has parameter”));

    MaterialInstance = UMaterialInstanceDynamic::Create(Material, this);
    if(MaterialInstance->GetParameterDesc(TEXT(“Test”), Desc))
    GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::, TEXT(“MaterialInstance has parameter”));

  5. Make a blueprint that inherits from this c++ class, and set the material to the one created in step 3.

  6. Press play, not that the first message appears but the second doesn’t (but should).

Hello ,

It appears that this is intended. While debugging the code that you provided to see why the if condition is failing, I see that the UMaterialInterface version of GetParameterDesc, which is what is called by UMaterialInstanceDynamic’s actually only returns false and has no other implementation, so this if check will always fail in this condition. The UMaterial version from UMaterial.cpp has a different function body.