tl;dr : call DynamicMeshComponent->MarkRenderStateDirty()
after setting the Material, but I don’t know if it’s safe.
Hello~
I need to change my Mesh Material at runtime, so I naturally went for the SetMaterial function.
It seems to work well on MeshComponent, but not on DynamicMeshComponent. The idea is to let the player create a mesh with the shape he wants, then apply a Material to this shape among several Materials available (and maybe tweak some Material parameters later on).
I tested DynamicMaterial, not working too (but not sure if I did things correctly with this).
So I decided to compare the source code of MeshComponent and DynamicMeshComponent SetMaterial() function, and the DynamicMeshComponent one is pretty… empty ?
DynamicMeshComponent overrides its parent’s MeshComponent SetMaterial function without calling it (which I can understand why), but neither reproduces its behavior.
Here is the DynamicMeshComponent SetMaterial function source code :
check(ElementIndex >= 0);
if (ElementIndex >= BaseMaterials.Num())
{
BaseMaterials.SetNum(ElementIndex + 1, false);
}
BaseMaterials[ElementIndex] = Material;
It basically just changes the BaseMaterial array, and nothing else. Whereas in the MeshComponent SetMaterial function source code (which I won’t c/p here because it’s longer and will make this post not pleasant to read) has calls to functions that dirties some states, updates and such…
My eyes went especially on those lines
// Set the material and invalidate things
OverrideMaterials[ElementIndex] = Material;
MarkRenderStateDirty();
In my despair, I made a manual call to MarkRenderStateDirty(), like this
void ADynamicSceneObject::SetMaterial(UMaterialInterface* NewMaterial)
{
DynamicMeshComponent->SetMaterial(0, NewMaterial);
DynamicMeshComponent->MarkRenderStateDirty();
}
And it worked… Even in an executable in shipping mode.
But now I wonder why it’s not written in the DynamicMeshComponent SetMaterial function, and if it is safe to make a manual call like this ?
If someone has any idea ^^
Thanks~