How to get a list of parameters from a material?

TLDR: how to access the parameters of a given material/material instance in BP and/or C++.

I would like to expose material parameters to the UI so the player can edit material instances at runtime(i.e. color, roughness of objects, etc).

I have a base class, that is the parent of everything in game; that has a variable of type Material Instance Dynamic called WMaterialInstance. It also has an Interface function to return that var.

Please see the construction script.

I’d like read parameters of this instance and expose it to the UI somehow.

But I can’t get those parameters…

I am using a Get Scalar Values node to get my params…

I tried feeding it a Material Instance Dynamic reference, but my Print String nodes return zero, although there are parameters on the material, 100%.

Please see the BP nodes here.

I found a postdescribing a similar issue.

One of the answers says:

So I got the parent of my Material Instance Dynamic and tried casting it to just a normal MaterialInstance, but the cast seems to fail, if I feed the parent to it…

Here is how I did it.

Note: the Get Material node is my interface call to the Dynamic Instance from construction script, not the built in one.

Further down in the post there is an answer saying:

I created a material instance from my original material and assigned it to one of the child classes of the baseclass, so I use that one in the base construction script.
Still, doesn’t want to work… I get the same zeros and cast failures…

I noticed, that if I Print String the Display name of the Parent I get from the accessed base material it prints WorldGridMaterial, which means, it did not find what it supposed to…

Did anyone experience something similar?

Is there a better way to access these parameters?

Couple things:

In that thread there is a conflation of a “material instance in the content browser” and a “material instance at runtime”. You can create material instances in the editor and apply them to meshes. But at runtime, in BeginPlay() not in constructor (at least in C++), you still need to create a dynamic material instance for meshes.

In C++ material instance is created like this:

UMaterialInstanceDynamic* matInstanceIndex_0 = CreateAndSetMaterialInstanceDynamic(0);

^ That gives you a handle to the dynamic material on the mesh. On which you can make calls to change material parameters.