x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Office Holiday

Epic Games' offices will be on holiday from June 22nd to July 7th. During this period support will be limited. Our offices will reopen on Monday, July 8th. 

Help, Materials, Parameters and C++ Problem

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. alt text

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.

Product Version: Not Selected
Tags:
more ▼

asked Jun 08 '17 at 11:11 PM in C++ Programming

avatar image

Bionic Ape
129 16 20 24

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

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.
         }
more ▼

answered Jun 09 '17 at 10:12 AM

avatar image

c4tnt
1k 13 8 31

avatar image Bionic Ape Jun 09 '17 at 03:05 PM

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.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question