UMaterialParameterCollection changes do not affect Material in C++

I have a material that uses “Material Parameter Collection” That has a property noise_scale

If while in the editor if I modify the Material Parameter Collection , scalar parameter “noise_scale” I can see the effect in real time.

However if I attempt this in code, using thefollowing code I see now change.

            FString collectionName = "MaterialParameterCollection'/Game/Sensor/uniforms.uniforms'";
            UMaterialParameterCollection* matParam = Cast<UMaterialParameterCollection>(StaticLoadObject(UMaterialParameterCollection::StaticClass(), NULL, *collectionName));
            bool isFound = false;
            if (matParam)
            {
                UE_LOG(LogTemp, Warning, TEXT("Found the Material Paramete Collection"));
                for (FCollectionScalarParameter param : matParam->ScalarParameters)
                {
                    if (param.ParameterName == "noise_scale")
                    {
                        UE_LOG(LogTemp, Warning, TEXT("noise_scale found and being set"));
                        param.DefaultValue = 6.0f;
                        isFound = true;
                    }
                }
            }
            else
            {
                UE_LOG(LogTemp, Warning, TEXT("Unable to find the Material Paramete Collection"));
            }

            if (isFound)
            {
                UE_LOG(LogTemp, Warning, TEXT("Set the parameter"));
            }
            else
            {
                UE_LOG(LogTemp, Warning, TEXT("Parameter not found, something is wrong"));
            }

Gives the following output

LogTemp:Warning: Found the Material Paramete Collection
LogTemp:Warning: noise_scale found and being set
LogTemp:Warning: Set the parameter

But visually I do not see the change.

However if I just modify the values in the editor while its running I do.

These properties will be shared acrss many different materials, so it seem this collection was the right way to go.

I believe an instance of the MaterialParameterCollection is created at runtime on the world, and you have to set through that. In the editor, changing a property actually is pretty complex (see UMaterialParameterCollection::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)

Try this:

  UMaterialParameterCollectionInstance *pInst = GetWorld()->GetParameterCollectionInstance( matParam);
    pInst->SetScalarParameterValue("noise_scale", 6.0f);

This is EXACTLY what I needed thanks. If you dont mind where is a good place t handle this kind of lookup. I am putting this in a USceneComponent which doesn’t have BeginPlay method. It seems that GetWorld() sometimes returns null in the constructor? Any tips thanks again!

I have typically put this sort of thing in the BeginPlay of my gamemode (1:1 correspondence with the world). Since you aren’t using an instance, you are using the entire global bundle, it makes sense to have it in a global object rather than a specific actor.

Thanks for the guidance. My issue was specifically with a component and not an actor. I ended doing it in the OnRegister event. Thanks again!