Help, Materials, Parameters and C++ Problem

Hi C4tnt,

Thanks for your answer.

Yes, I ended up doing something similar.

An Actor Component that tracks and creates dynamic materials when are needed.
4 Arrays of weak references to materials, one per Parameter. So when we create the dynamic material, we check which parameters does it have and we add a weak reference of that material to the corresponding Array. So if that material has 3 parameters (A,B,D) we add a weak ref to arrayA, ArrayB, ArrayD.
4 Delegates “OnChangeParameterX”, one per parameter.
And the character broadcast when a value changes.
The Actor Component executes “OnChangeParameterA” (e.g) and updates the full arrayA.

Many thanks! You are brilliant.

Hi,

I can’t get my head around this. I am sure Unreal has a clean/elegant solution for this.

The Problem:

  • Imagine I have Characters that make use of different Skeletals. Each Character creates a set of UMaterialInstanceDynamic for each skeletal.
  • The Skeletals have around 15 Materials,each material can make use (or not) of 4 Parameters that correspond to 4 Properties of the Character.
  • The parameters have to be updated every tick.
  • Every Skeletal that the Character can have has different amount and kind of Materials.

I have found 2 Possible solutions I would like to Implement, but I can’t get it working.

I have also found an ugly solution.

The ugly solution is getting all the UMaterialInstanceDynamic and update the parameters that needs, checking if that parameter is needed (an exception is thrown if when a parameter that the material Instance doesn’t have is set).

The Nice Solution 1 would be to have a ParameterCollection specific for that character and that set of Materials. But as far as I know, ParameterCollectionInstances belong to UWorld and only one is created per ParameterCollection;

The Nice Solution 2 is to bind a C++ function to the material, so when each parameter is needed by the Materials that function is executed.

What should I do?, Please help!

Thanks.

Hi. You can create a new actor (not scene) component ( UParamAnnouncerComponent or something like this ) which will walk thru the actor hierarchy and set dynamic instances on meshes which default material have specific parameters. Also this component should save information about that material instances. At least you have to store TArray of UMaterialDynamicInstances weak references there to refresh all parameters when you need. Using weak references prevents from memory leakage when you change some materials on your character. If you change some material ingame old dynamic instance is still be referenced from the TArray without using weak refs. Also this component can hold previous variables for parameters (or hashes - it will be less complicated) and perform actual update only when something is really changed instead of each frame updates.

When created this component can be attached to any character or static object you want and expose some update functions to a blueprint.

How to get param names if you have a material reference:

		UMaterial* Material = GetMaterial(); // You can do this somehow, depending on what data you have. Anyway MaterialInterface provides this function.

		//setup some arrays to use
		TArray<FName> Names;
		TArray<FGuid> Guids;    // Inaccessible in shipping but should be provided to the following function.

		Material->GetAllScalarParameterNames(Names, Guids);
		for(int32 i = 0, Size = Names.Num(); i < Size; ++i)
		{
			FName ParameterName = Names[i];
            // Save names and decide to replace or not this material by a dynamic instance.
		}