'Instanced Materials' Dynamic Material Instance

Dynamic Material Instances are pretty cool and more flexible than creating separate assets.


Here are my two dudes. I had a quick play with the parameters (not pictured), but being colour challenged they just looked weird. Quite surprised that no one made an Iron Man Steve…

I Created this with Dynamic Material instances. It was very good practice! Dynamic Material instance means, that you can change any parameter in materials, without needing to create seperate materials. This is how it works:

First lets change the header file in ThirdPerson Character. We create a UMaterialInstanceDynamic called DynMaterial and UMaterialInterface called MaterialToEdit. We also create a FLinearColor that is a struct. Notice that struct is not pointer!

UPROPERTY()
UMaterialInstanceDynamic* DynMaterial;

UPROPERTY(EditDefaultsOnly, Category = "Material")
UMaterialInterface* MaterialToEdit;

UPROPERTY(EditAnywhere, Category = "Mesh")
FLinearColor NewColor;

In UMaterialInstanceDynamic we leave UPROPERTY blank, because we don’t need to change it in editor or instance. UMaterialInterface is EditDefaultsOnly,because we just want to set it in Defaults screen. FLinearColor is EditAnywhere so we can change it anywhere. Category is Mesh, so it is easy to find.

Now, we need to create Construction Script in C++. It was rather easy. You just type:
virtual void OnConstruction(const FTransform& Transform) override;

Lets go to .CPP.
Lets create implementation for our construction script first:

void ATP_ThirdPersonCharacter::OnConstruction(const FTransform& Transform)
{ 
}

Finally we set our dynamic material Code inside the script

void ATP_ThirdPersonCharacter::OnConstruction(const FTransform& Transform)
{
	DynMaterial = UMaterialInstanceDynamic::Create(MaterialToEdit, this);
	GetMesh()->SetMaterial(0, DynMaterial);
	DynMaterial->SetVectorParameterValue("BodyColor", NewColor);
}

What we do here is, we create a Dynamic material from the material we set in ‘MaterialToEdit’. Then we get our mesh and set that material in element 0. Then we change the parameter called “BodyColor” and set the value to be the “NewColor” we can later change in editor or instance.

Finally, we need to go inside our thirdPersonCharacter and set the Material to edit. Naturally, we say the material to be the M_UEMan_Body. Because that is the original material the characters used.


Thats it. Now if we look our characters, we can set them to be any color we ever want by just changing the NewColor variable that is exposed in editor!.

Just wanted to share this! This was a big learning process! Cheers!

4 Likes

played around with the parameters a bit. Change the logo so it is the same across all instances, Steve is blue with red accents, and Harry is red with Blue accents. Gives them a touch more variety and detail.

very nice, but couldnt you have done that in the thirdpersoncharacters constructor?

isnt OnConstruction(const FTransform& Transform) only needed if you need access to the transform which you didnt use anyway.

Hi! Thanks for comment! If you mean normal constructor then no. Normal constructor only loads once, when you compile project. Construction runs every time when even the smallest thing changes within the actor. So when we change the Color-variable, the OnConstruct() will fire and the color will change realtime. OnConstruct() is similar to blueprint Construction. I don’t know why there isn’t a parameter coming out in Blueprint. It comes out as a default in C++.

ah yes. makes sense you would have to compile to update changes with the normal constructor where as the OnConstruct() is called from the editor when changes are made in real time. thanks man.

again red and blue are a nice combination

Thank you it’s good idea

This is great! never even thought about the possibility of playing with those in code! Thanks!

In UE 4.21.2, using constructor TP_ThirdPersonCharacter::ATP_ThirdPersonCharacter() crash the editor. OnConstruction(const FTransform& Transform) works properly. It’s called whenever the character is spawned in the scene or any of its component values is changed. Works in edit and play mode. There’s also a possibility to run this code in BeginPlay() but then the instanced material is only visible on the character in play mode.

Privacy & Terms