While our game may be running without any issues in the editor or even in…
Dynamic Materials – Communicating with the Material Editor using C++
In this post we’re going to see how we can communicate with the Material Editor and change specific parameters of our Materials during runtime.
Creating a dummy Material
Create a material which consists of two parameters:
- A Vector Parameter, connected to the base color input
- A Scalar Parameter, connected to the metallic value
Here is a screenshot of my material so far:
Note that I’ve named both parameters with a desired name. In order to name a parameter, click on it and then modify the Parameter Name value.
Accessing material parameters
Create a C++ class which inherits the Actor class and add the following component inside the header file:
1 2 3 |
/*The static mesh of the actor*/ UPROPERTY(VisibleAnywhere) UStaticMeshComponent* StaticMesh; |
Then, inside the source file, type in the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// Sets default values AColorActor::AColorActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; //Initialize the static mesh component StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(FName("StaticMesh")); } // Called when the game starts or when spawned void AColorActor::BeginPlay() { Super::BeginPlay(); //Get the first material of the static mesh and turn it into a material instance UMaterialInstanceDynamic* DynamicMatInstance = StaticMesh->CreateAndSetMaterialInstanceDynamic(0); //Generate random RGB and Alpha values for our Vector Parameter FLinearColor RandomColor; RandomColor.R = FMath::RandRange(0, 1); RandomColor.G = FMath::RandRange(0, 1); RandomColor.B = FMath::RandRange(0, 1); RandomColor.A = FMath::RandRange(0, 1); //If we have a valid dynamic material instance, modify its parameters if (DynamicMatInstance) { DynamicMatInstance->SetVectorParameterValue(FName("ColorParam"), RandomColor); DynamicMatInstance->SetScalarParameterValue(FName("MetalParam"), FMath::RandRange(0, 1)); } } |
Once you’re done with that, compile your code and create a Blueprint based on your C++ class. Then, choose a static mesh of your desire and assign to the first Material slot the material you have created in the first step of this post:
When you’re done with that, place some actors on your level and play the game.
Check out some results of mine:
Hi.
Is there a way to determine what material parameters are on an already instanced material? Thanks for your tutorials!
teak
Hmm… Don’t see my other comment, might be moderated?
One more question… Along the same lines of my previous question… See how you’ve hard-coded the parameter above, is there a way for C++ to determine what available parameters are available on a specific material? (similar to my previous question, but more specific). Thanks again.
teak
Hello, to answer both of your questions:
You can get a parameter by using the following script: http://pastebin.com/PRVG04hs
I assume, (I’ve never used it before) that you are able to get the available parameters by using GetStaticParameterValues or GetNativePropertyValues function (both are located in the UMaterialInstanceDynamic class) depending on your needs.
-Orfeas
Hi,
Not sure if you answered the question @Micheal Gaskin asked. But, I had a question on similar lines –
1. Is it possible to create a new parameter and assign it to a dynamic instance of a material. For eg. similar to your program,
UMaterialInstanceDynamic* DynamicMatInstance = StaticMesh->CreateAndSetMaterialInstanceDynamic(0);
This StaticMesh’s material will not have any params i.e. no ‘ColorParam’ and no ‘MetalParam’. I want to create these params in C++ code and attach them to ‘BaseColor’ and ‘Metallic’.
Is that possible?
Thank you for this tutorial! It works, however there is a major issue.
This material change does not work if the instance you’re changing was spawned during gameplay from C++ and not clicked into scene through the editor.
I am using version 4.25.0
Also, is it possible to change material parameters on a decal? I tried to do that, but this function does not exist on UDecalComponent:
UDecalComponent::CreateAndSetMaterialInstanceDynamic(0);
Is there any equivalent to this?